Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
[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_SUBKEY_SD);
852         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
853
854         return true;
855 }
856
857 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
858                                                     struct torture_context *tctx,
859                                                     struct policy_handle *handle,
860                                                     const char *key)
861 {
862         /* get sd
863            add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
864            set sd
865            add subkey/subkey
866            get sd
867            check ace
868            get sd from subkey
869            check ace
870            del subkey/subkey
871            del subkey
872            reset sd
873         */
874
875         struct security_descriptor *sd = NULL;
876         struct security_descriptor *sd_orig = NULL;
877         struct security_ace *ace = NULL;
878         struct policy_handle new_handle;
879         struct dom_sid *sid = NULL;
880         NTSTATUS status;
881         bool ret = true;
882         uint8_t ace_flags = 0x0;
883
884         torture_comment(tctx, "SecurityDescriptor inheritance block\n");
885
886         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
887                 return false;
888         }
889
890         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
891                 return false;
892         }
893
894         sd_orig = security_descriptor_copy(tctx, sd);
895         if (sd_orig == NULL) {
896                 return false;
897         }
898
899         ace = security_ace_create(tctx,
900                                   TEST_SID,
901                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
902                                   SEC_STD_REQUIRED,
903                                   SEC_ACE_FLAG_CONTAINER_INHERIT |
904                                   SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
905
906         status = security_descriptor_dacl_add(sd, ace);
907         if (!NT_STATUS_IS_OK(status)) {
908                 printf("failed to add ace: %s\n", nt_errstr(status));
909                 return false;
910         }
911
912         if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
913                 return false;
914         }
915
916         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
917                 printf("new ACE not present!\n");
918                 return false;
919         }
920
921         if (!test_CloseKey(p, tctx, &new_handle)) {
922                 return false;
923         }
924
925         if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
926                 return false;
927         }
928
929         if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
930                 ret = false;
931                 goto out;
932         }
933
934         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
935                 printf("inherited ACE present but should not!\n");
936                 ret = false;
937                 goto out;
938         }
939
940         sid = dom_sid_parse_talloc(tctx, TEST_SID);
941         if (sid == NULL) {
942                 return false;
943         }
944
945         if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
946                 printf("inherited trustee SID present but should not!\n");
947                 ret = false;
948                 goto out;
949         }
950
951         test_CloseKey(p, tctx, &new_handle);
952
953         if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
954                 ret = false;
955                 goto out;
956         }
957
958         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
959                 printf("inherited ACE present but should not!\n");
960                 ret = false;
961                 goto out;
962         }
963
964         if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
965                 printf("inherited trustee SID with flags 0x%02x not present!\n",
966                         ace_flags);
967                 ret = false;
968                 goto out;
969         }
970
971  out:
972         test_CloseKey(p, tctx, &new_handle);
973         test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
974         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
975
976         return ret;
977 }
978
979 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
980                                           struct torture_context *tctx,
981                                           struct policy_handle *handle,
982                                           const char *key)
983 {
984         bool ret = true;
985         int i;
986
987         struct winreg_mask_result_table {
988                 uint32_t access_mask;
989                 WERROR open_werr;
990                 WERROR get_werr;
991                 WERROR set_werr;
992         } sd_mask_tests[] = {
993                 { 0,
994                         WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
995                 { SEC_FLAG_MAXIMUM_ALLOWED,
996                         WERR_OK, WERR_OK, WERR_OK },
997                 { SEC_STD_WRITE_DAC,
998                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
999                 { SEC_FLAG_SYSTEM_SECURITY,
1000                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1001         };
1002
1003         /* FIXME: before this test can ever run successfully we need a way to
1004          * correctly read a NULL security_descritpor in ndr, get the required
1005          * length, requery, etc.
1006          */
1007
1008         return true;
1009
1010         for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1011
1012                 torture_comment(tctx,
1013                                 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1014                                 sd_mask_tests[i].access_mask);
1015                 torture_comment(tctx,
1016                                 "expecting: open %s, get: %s, set: %s\n",
1017                                 win_errstr(sd_mask_tests[i].open_werr),
1018                                 win_errstr(sd_mask_tests[i].get_werr),
1019                                 win_errstr(sd_mask_tests[i].set_werr));
1020
1021                 if (_test_SecurityDescriptor(p, tctx, handle,
1022                                              sd_mask_tests[i].access_mask, key,
1023                                              sd_mask_tests[i].open_werr,
1024                                              sd_mask_tests[i].get_werr,
1025                                              sd_mask_tests[i].set_werr)) {
1026                         ret = false;
1027                 }
1028         }
1029
1030         return ret;
1031 }
1032
1033 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1034                                   struct torture_context *,
1035                                   struct policy_handle *,
1036                                   const char *,
1037                                   const struct dom_sid *);
1038
1039 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1040                                                struct torture_context *tctx,
1041                                                struct policy_handle *handle,
1042                                                const char *key,
1043                                                const char *test,
1044                                                uint32_t access_mask,
1045                                                uint32_t sec_info,
1046                                                struct security_descriptor *sd,
1047                                                WERROR set_werr,
1048                                                bool expect_present,
1049                                                bool (*fn) (struct dcerpc_pipe *,
1050                                                            struct torture_context *,
1051                                                            struct policy_handle *,
1052                                                            const char *,
1053                                                            const struct dom_sid *),
1054                                                const struct dom_sid *sid)
1055 {
1056         struct policy_handle new_handle;
1057         bool open_success = false;
1058
1059         torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1060                         "0x%08x, access_mask: 0x%08x\n",
1061                         test, sec_info, access_mask);
1062
1063         if (!_test_OpenKey(p, tctx, handle, key,
1064                            access_mask,
1065                            &new_handle,
1066                            WERR_OK,
1067                            &open_success)) {
1068                 return false;
1069         }
1070
1071         if (!open_success) {
1072                 printf("key did not open\n");
1073                 test_CloseKey(p, tctx, &new_handle);
1074                 return false;
1075         }
1076
1077         if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1078                                   sd,
1079                                   set_werr)) {
1080                 torture_warning(tctx,
1081                                 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1082                                 sec_info);
1083                 smb_panic("");
1084                 test_CloseKey(p, tctx, &new_handle);
1085                 return false;
1086         }
1087
1088         test_CloseKey(p, tctx, &new_handle);
1089
1090         if (W_ERROR_IS_OK(set_werr)) {
1091                 bool present;
1092                 present = fn(p, tctx, handle, key, sid);
1093                 if ((expect_present) && (!present)) {
1094                         torture_warning(tctx,
1095                                         "%s sid is not present!\n",
1096                                         test);
1097                         return false;
1098                 }
1099                 if ((!expect_present) && (present)) {
1100                         torture_warning(tctx,
1101                                         "%s sid is present but not expected!\n",
1102                                         test);
1103                         return false;
1104                 }
1105         }
1106
1107         return true;
1108 }
1109
1110 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1111                                             struct torture_context *tctx,
1112                                             struct policy_handle *handle,
1113                                             const char *key)
1114 {
1115         struct security_descriptor *sd_orig = NULL;
1116         struct dom_sid *sid = NULL;
1117         bool ret = true;
1118         int i, a;
1119
1120         struct security_descriptor *sd_owner =
1121                 security_descriptor_dacl_create(tctx,
1122                                                 0,
1123                                                 TEST_SID, NULL, NULL);
1124
1125         struct security_descriptor *sd_group =
1126                 security_descriptor_dacl_create(tctx,
1127                                                 0,
1128                                                 NULL, TEST_SID, NULL);
1129
1130         struct security_descriptor *sd_dacl =
1131                 security_descriptor_dacl_create(tctx,
1132                                                 0,
1133                                                 NULL, NULL,
1134                                                 TEST_SID,
1135                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1136                                                 SEC_GENERIC_ALL,
1137                                                 0,
1138                                                 SID_NT_AUTHENTICATED_USERS,
1139                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1140                                                 SEC_GENERIC_ALL,
1141                                                 0,
1142                                                 NULL);
1143
1144         struct security_descriptor *sd_sacl =
1145                 security_descriptor_sacl_create(tctx,
1146                                                 0,
1147                                                 NULL, NULL,
1148                                                 TEST_SID,
1149                                                 SEC_ACE_TYPE_SYSTEM_AUDIT,
1150                                                 SEC_GENERIC_ALL,
1151                                                 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1152                                                 NULL);
1153
1154         struct winreg_secinfo_table {
1155                 struct security_descriptor *sd;
1156                 uint32_t sec_info;
1157                 WERROR set_werr;
1158                 bool sid_present;
1159                 secinfo_verify_fn fn;
1160         };
1161
1162         struct winreg_secinfo_table sec_info_owner_tests[] = {
1163                 { sd_owner, 0, WERR_OK,
1164                         false, (secinfo_verify_fn)_test_owner_present },
1165                 { sd_owner, SECINFO_OWNER, WERR_OK,
1166                         true, (secinfo_verify_fn)_test_owner_present },
1167                 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1168                 { sd_owner, SECINFO_DACL, WERR_OK,
1169                         true, (secinfo_verify_fn)_test_owner_present },
1170                 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1171         };
1172
1173         uint32_t sd_owner_good_access_masks[] = {
1174                 SEC_FLAG_MAXIMUM_ALLOWED,
1175                 /* SEC_STD_WRITE_OWNER, */
1176         };
1177
1178         struct winreg_secinfo_table sec_info_group_tests[] = {
1179                 { sd_group, 0, WERR_OK,
1180                         false, (secinfo_verify_fn)_test_group_present },
1181                 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1182                 { sd_group, SECINFO_GROUP, WERR_OK,
1183                         true, (secinfo_verify_fn)_test_group_present },
1184                 { sd_group, SECINFO_DACL, WERR_OK,
1185                         true, (secinfo_verify_fn)_test_group_present },
1186                 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1187         };
1188
1189         uint32_t sd_group_good_access_masks[] = {
1190                 SEC_FLAG_MAXIMUM_ALLOWED,
1191         };
1192
1193         struct winreg_secinfo_table sec_info_dacl_tests[] = {
1194                 { sd_dacl, 0, WERR_OK,
1195                         false, (secinfo_verify_fn)_test_dacl_trustee_present },
1196                 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1197                 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1198                 { sd_dacl, SECINFO_DACL, WERR_OK,
1199                         true, (secinfo_verify_fn)_test_dacl_trustee_present },
1200                 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1201         };
1202
1203         uint32_t sd_dacl_good_access_masks[] = {
1204                 SEC_FLAG_MAXIMUM_ALLOWED,
1205                 SEC_STD_WRITE_DAC,
1206         };
1207
1208         struct winreg_secinfo_table sec_info_sacl_tests[] = {
1209                 { sd_sacl, 0, WERR_OK,
1210                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1211                 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1212                 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1213                 { sd_sacl, SECINFO_DACL, WERR_OK,
1214                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1215                 { sd_sacl, SECINFO_SACL, WERR_OK,
1216                         true, (secinfo_verify_fn)_test_sacl_trustee_present },
1217         };
1218
1219         uint32_t sd_sacl_good_access_masks[] = {
1220                 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1221                 /* SEC_FLAG_SYSTEM_SECURITY, */
1222         };
1223
1224         sid = dom_sid_parse_talloc(tctx, TEST_SID);
1225         if (sid == NULL) {
1226                 return false;
1227         }
1228
1229         if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1230                 return false;
1231         }
1232
1233         /* OWNER */
1234
1235         for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1236
1237                 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1238
1239                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1240                                         key,
1241                                         "OWNER",
1242                                         sd_owner_good_access_masks[a],
1243                                         sec_info_owner_tests[i].sec_info,
1244                                         sec_info_owner_tests[i].sd,
1245                                         sec_info_owner_tests[i].set_werr,
1246                                         sec_info_owner_tests[i].sid_present,
1247                                         sec_info_owner_tests[i].fn,
1248                                         sid))
1249                         {
1250                                 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1251                                 ret = false;
1252                                 goto out;
1253                         }
1254                 }
1255         }
1256
1257         /* GROUP */
1258
1259         for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1260
1261                 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1262
1263                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1264                                         key,
1265                                         "GROUP",
1266                                         sd_group_good_access_masks[a],
1267                                         sec_info_group_tests[i].sec_info,
1268                                         sec_info_group_tests[i].sd,
1269                                         sec_info_group_tests[i].set_werr,
1270                                         sec_info_group_tests[i].sid_present,
1271                                         sec_info_group_tests[i].fn,
1272                                         sid))
1273                         {
1274                                 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1275                                 ret = false;
1276                                 goto out;
1277                         }
1278                 }
1279         }
1280
1281         /* DACL */
1282
1283         for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1284
1285                 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1286
1287                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1288                                         key,
1289                                         "DACL",
1290                                         sd_dacl_good_access_masks[a],
1291                                         sec_info_dacl_tests[i].sec_info,
1292                                         sec_info_dacl_tests[i].sd,
1293                                         sec_info_dacl_tests[i].set_werr,
1294                                         sec_info_dacl_tests[i].sid_present,
1295                                         sec_info_dacl_tests[i].fn,
1296                                         sid))
1297                         {
1298                                 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1299                                 ret = false;
1300                                 goto out;
1301                         }
1302                 }
1303         }
1304
1305         /* SACL */
1306
1307         for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1308
1309                 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1310
1311                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1312                                         key,
1313                                         "SACL",
1314                                         sd_sacl_good_access_masks[a],
1315                                         sec_info_sacl_tests[i].sec_info,
1316                                         sec_info_sacl_tests[i].sd,
1317                                         sec_info_sacl_tests[i].set_werr,
1318                                         sec_info_sacl_tests[i].sid_present,
1319                                         sec_info_sacl_tests[i].fn,
1320                                         sid))
1321                         {
1322                                 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1323                                 ret = false;
1324                                 goto out;
1325                         }
1326                 }
1327         }
1328
1329  out:
1330         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1331
1332         return ret;
1333 }
1334
1335 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1336                                      struct torture_context *tctx,
1337                                      struct policy_handle *handle,
1338                                      const char *key)
1339 {
1340         bool ret = true;
1341
1342         if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1343                 printf("test_SecurityDescriptor failed\n");
1344                 ret = false;
1345         }
1346
1347         if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1348                 printf("test_SecurityDescriptorInheritance failed\n");
1349                 ret = false;
1350         }
1351
1352         if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1353                 printf("test_SecurityDescriptorBlockInheritance failed\n");
1354                 ret = false;
1355         }
1356
1357         if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1358                 printf("test_SecurityDescriptorsSecInfo failed\n");
1359                 ret = false;
1360         }
1361
1362         if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1363                 printf("test_SecurityDescriptorsMasks failed\n");
1364                 ret = false;
1365         }
1366
1367         return ret;
1368 }
1369
1370 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1371                            struct policy_handle *handle, const char *key)
1372 {
1373         NTSTATUS status;
1374         struct winreg_DeleteKey r;
1375
1376         r.in.handle = handle;
1377         init_winreg_String(&r.in.key, key);
1378
1379         status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1380
1381         torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1382         torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1383
1384         return true;
1385 }
1386
1387 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1388                               struct torture_context *tctx,
1389                               struct policy_handle *handle, char *class)
1390 {
1391         struct winreg_QueryInfoKey r;
1392         uint32_t num_subkeys, max_subkeylen, max_subkeysize,
1393                 num_values, max_valnamelen, max_valbufsize,
1394                 secdescsize;
1395         NTTIME last_changed_time;
1396
1397         ZERO_STRUCT(r);
1398         r.in.handle = handle;
1399         r.out.num_subkeys = &num_subkeys;
1400         r.out.max_subkeylen = &max_subkeylen;
1401         r.out.max_subkeysize = &max_subkeysize;
1402         r.out.num_values = &num_values;
1403         r.out.max_valnamelen = &max_valnamelen;
1404         r.out.max_valbufsize = &max_valbufsize;
1405         r.out.secdescsize = &secdescsize;
1406         r.out.last_changed_time = &last_changed_time;
1407
1408         r.out.classname = talloc(tctx, struct winreg_String);
1409
1410         r.in.classname = talloc(tctx, struct winreg_String);
1411         init_winreg_String(r.in.classname, class);
1412
1413         torture_assert_ntstatus_ok(tctx,
1414                                    dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1415                                    "QueryInfoKey failed");
1416
1417         torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1418
1419         return true;
1420 }
1421
1422 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1423                      struct policy_handle *handle, int depth,
1424                      bool test_security);
1425
1426 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1427                          struct policy_handle *handle, int depth,
1428                          bool test_security)
1429 {
1430         struct winreg_EnumKey r;
1431         struct winreg_StringBuf class, name;
1432         NTSTATUS status;
1433         NTTIME t = 0;
1434
1435         class.name   = "";
1436         class.size   = 1024;
1437
1438         r.in.handle = handle;
1439         r.in.enum_index = 0;
1440         r.in.name = &name;
1441         r.in.keyclass = &class;
1442         r.out.name = &name;
1443         r.in.last_changed_time = &t;
1444
1445         do {
1446                 name.name   = NULL;
1447                 name.size   = 1024;
1448
1449                 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1450
1451                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1452                         struct policy_handle key_handle;
1453
1454                         torture_comment(tctx, "EnumKey: %d: %s\n",
1455                                         r.in.enum_index,
1456                                         r.out.name->name);
1457
1458                         if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1459                                           &key_handle)) {
1460                         } else {
1461                                 test_key(p, tctx, &key_handle,
1462                                          depth + 1, test_security);
1463                         }
1464                 }
1465
1466                 r.in.enum_index++;
1467
1468         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1469
1470         torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1471
1472         if (!W_ERROR_IS_OK(r.out.result) &&
1473                 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1474                 torture_fail(tctx, "EnumKey failed");
1475         }
1476
1477         return true;
1478 }
1479
1480 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1481                                      struct torture_context *tctx,
1482                                      struct policy_handle *handle,
1483                                      const char *valuename)
1484 {
1485         struct winreg_QueryMultipleValues r;
1486         NTSTATUS status;
1487         uint32_t bufsize=0;
1488
1489         r.in.key_handle = handle;
1490         r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1491         r.in.values[0].name = talloc(tctx, struct winreg_String);
1492         r.in.values[0].name->name = valuename;
1493         r.in.values[0].offset = 0;
1494         r.in.values[0].length = 0;
1495         r.in.values[0].type = 0;
1496
1497         r.in.num_values = 1;
1498         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1499         *r.in.buffer_size = bufsize;
1500         do {
1501                 *r.in.buffer_size = bufsize;
1502                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1503                                                                *r.in.buffer_size);
1504
1505                 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1506
1507                 if(NT_STATUS_IS_ERR(status))
1508                         torture_fail(tctx, "QueryMultipleValues failed");
1509
1510                 talloc_free(r.in.buffer);
1511                 bufsize += 0x20;
1512         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1513
1514         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1515
1516         return true;
1517 }
1518
1519 static bool test_QueryValue(struct dcerpc_pipe *p,
1520                             struct torture_context *tctx,
1521                             struct policy_handle *handle,
1522                             const char *valuename)
1523 {
1524         struct winreg_QueryValue r;
1525         NTSTATUS status;
1526         enum winreg_Type zero_type = 0;
1527         uint32_t offered = 0xfff;
1528         uint32_t zero = 0;
1529
1530         r.in.handle = handle;
1531         r.in.data = NULL;
1532         r.in.value_name.name = valuename;
1533         r.in.type = &zero_type;
1534         r.in.size = &offered;
1535         r.in.length = &zero;
1536
1537         status = dcerpc_winreg_QueryValue(p, tctx, &r);
1538         if (NT_STATUS_IS_ERR(status)) {
1539                 torture_fail(tctx, "QueryValue failed");
1540         }
1541
1542         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1543
1544         return true;
1545 }
1546
1547 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1548                            struct policy_handle *handle, int max_valnamelen,
1549                            int max_valbufsize)
1550 {
1551         struct winreg_EnumValue r;
1552         enum winreg_Type type = 0;
1553         uint32_t size = max_valbufsize, zero = 0;
1554         bool ret = true;
1555         uint8_t buf8;
1556         struct winreg_StringBuf name;
1557
1558         name.name   = "";
1559         name.size   = 1024;
1560
1561         r.in.handle = handle;
1562         r.in.enum_index = 0;
1563         r.in.name = &name;
1564         r.out.name = &name;
1565         r.in.type = &type;
1566         r.in.value = &buf8;
1567         r.in.length = &zero;
1568         r.in.size = &size;
1569
1570         do {
1571                 torture_assert_ntstatus_ok(tctx,
1572                                            dcerpc_winreg_EnumValue(p, tctx, &r),
1573                                            "EnumValue failed");
1574
1575                 if (W_ERROR_IS_OK(r.out.result)) {
1576                         ret &= test_QueryValue(p, tctx, handle,
1577                                                r.out.name->name);
1578                         ret &= test_QueryMultipleValues(p, tctx, handle,
1579                                                         r.out.name->name);
1580                 }
1581
1582                 r.in.enum_index++;
1583         } while (W_ERROR_IS_OK(r.out.result));
1584
1585         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1586                                   "EnumValue failed");
1587
1588         return ret;
1589 }
1590
1591 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1592                                      struct torture_context *tctx)
1593 {
1594         struct winreg_AbortSystemShutdown r;
1595         uint16_t server = 0x0;
1596
1597         r.in.server = &server;
1598
1599         torture_assert_ntstatus_ok(tctx,
1600                                    dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1601                                    "AbortSystemShutdown failed");
1602
1603         torture_assert_werr_ok(tctx, r.out.result,
1604                                "AbortSystemShutdown failed");
1605
1606         return true;
1607 }
1608
1609 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1610                                         struct dcerpc_pipe *p)
1611 {
1612         struct winreg_InitiateSystemShutdown r;
1613         uint16_t hostname = 0x0;
1614
1615         r.in.hostname = &hostname;
1616         r.in.message = talloc(tctx, struct lsa_StringLarge);
1617         init_lsa_StringLarge(r.in.message, "spottyfood");
1618         r.in.force_apps = 1;
1619         r.in.timeout = 30;
1620         r.in.reboot = 1;
1621
1622         torture_assert_ntstatus_ok(tctx,
1623                                    dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1624                                    "InitiateSystemShutdown failed");
1625
1626         torture_assert_werr_ok(tctx, r.out.result,
1627                                "InitiateSystemShutdown failed");
1628
1629         return test_AbortSystemShutdown(p, tctx);
1630 }
1631
1632
1633 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1634                                           struct dcerpc_pipe *p)
1635 {
1636         struct winreg_InitiateSystemShutdownEx r;
1637         uint16_t hostname = 0x0;
1638
1639         r.in.hostname = &hostname;
1640         r.in.message = talloc(tctx, struct lsa_StringLarge);
1641         init_lsa_StringLarge(r.in.message, "spottyfood");
1642         r.in.force_apps = 1;
1643         r.in.timeout = 30;
1644         r.in.reboot = 1;
1645         r.in.reason = 0;
1646
1647         torture_assert_ntstatus_ok(tctx,
1648                 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1649                 "InitiateSystemShutdownEx failed");
1650
1651         torture_assert_werr_ok(tctx, r.out.result,
1652                                "InitiateSystemShutdownEx failed");
1653
1654         return test_AbortSystemShutdown(p, tctx);
1655 }
1656 #define MAX_DEPTH 2             /* Only go this far down the tree */
1657
1658 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1659                      struct policy_handle *handle, int depth,
1660                      bool test_security)
1661 {
1662         if (depth == MAX_DEPTH)
1663                 return true;
1664
1665         if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1666         }
1667
1668         if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1669         }
1670
1671         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1672         }
1673
1674         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1675         }
1676
1677         if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1678         }
1679
1680         test_CloseKey(p, tctx, handle);
1681
1682         return true;
1683 }
1684
1685 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1686
1687 static bool test_Open_Security(struct torture_context *tctx,
1688                                struct dcerpc_pipe *p, void *userdata)
1689 {
1690         struct policy_handle handle, newhandle;
1691         bool ret = true, created2 = false;
1692         bool created4 = false;
1693         struct winreg_OpenHKLM r;
1694
1695         winreg_open_fn open_fn = userdata;
1696
1697         r.in.system_name = 0;
1698         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1699         r.out.handle = &handle;
1700
1701         torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1702                                    "open");
1703
1704         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1705
1706         if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1707                 torture_comment(tctx,
1708                                 "CreateKey (TEST_KEY_BASE) failed\n");
1709         }
1710
1711         if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1712                               NULL, &newhandle)) {
1713                 created2 = true;
1714         }
1715
1716         if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1717                 printf("CloseKey failed\n");
1718                 ret = false;
1719         }
1720
1721         if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1722                 created4 = true;
1723         }
1724
1725         if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1726                 printf("CloseKey failed\n");
1727                 ret = false;
1728         }
1729
1730         if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1731                 ret = false;
1732         }
1733
1734         if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1735                 printf("DeleteKey failed\n");
1736                 ret = false;
1737         }
1738
1739         if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1740                 printf("DeleteKey failed\n");
1741                 ret = false;
1742         }
1743
1744         /* The HKCR hive has a very large fanout */
1745         if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1746                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
1747                         ret = false;
1748                 }
1749         } else {
1750                 if (!test_key(p, tctx, &handle, 0, true)) {
1751                         ret = false;
1752                 }
1753         }
1754
1755         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1756
1757         return ret;
1758 }
1759
1760 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1761                       void *userdata)
1762 {
1763         struct policy_handle handle, newhandle;
1764         bool ret = true, created = false, deleted = false;
1765         bool created3 = false, created_subkey = false;
1766         struct winreg_OpenHKLM r;
1767
1768         winreg_open_fn open_fn = userdata;
1769
1770         r.in.system_name = 0;
1771         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1772         r.out.handle = &handle;
1773
1774         torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1775                                    "open");
1776
1777         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1778
1779         if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1780                 torture_comment(tctx,
1781                                 "CreateKey (TEST_KEY_BASE) failed\n");
1782         }
1783
1784         if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1785                 torture_comment(tctx,
1786                                 "CreateKey failed - not considering a failure\n");
1787         } else {
1788                 created = true;
1789         }
1790
1791         if (created && !test_FlushKey(p, tctx, &handle)) {
1792                 torture_comment(tctx, "FlushKey failed\n");
1793                 ret = false;
1794         }
1795
1796         if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1797                 torture_fail(tctx,
1798                              "CreateKey failed (OpenKey after Create didn't work)\n");
1799
1800         if (created && !test_CloseKey(p, tctx, &newhandle))
1801                 torture_fail(tctx,
1802                              "CreateKey failed (CloseKey after Open didn't work)\n");
1803
1804         if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1805                 torture_comment(tctx, "DeleteKey failed\n");
1806                 ret = false;
1807         } else {
1808                 deleted = true;
1809         }
1810
1811         if (created && !test_FlushKey(p, tctx, &handle)) {
1812                 torture_comment(tctx, "FlushKey failed\n");
1813                 ret = false;
1814         }
1815
1816         if (created && deleted &&
1817             !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
1818                            SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
1819                            WERR_BADFILE, NULL)) {
1820                 torture_comment(tctx,
1821                                 "DeleteKey failed (OpenKey after Delete "
1822                                 "did not return WERR_BADFILE)\n");
1823                 ret = false;
1824         }
1825
1826         if (!test_GetVersion(p, tctx, &handle)) {
1827                 torture_comment(tctx, "GetVersion failed\n");
1828                 ret = false;
1829         }
1830
1831         if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
1832                 created3 = true;
1833         }
1834
1835         if (created3 &&
1836             test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
1837                 created_subkey = true;
1838         }
1839
1840         if (created_subkey &&
1841             !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
1842                 printf("DeleteKey failed\n");
1843                 ret = false;
1844         }
1845
1846         /* The HKCR hive has a very large fanout */
1847         if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1848                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
1849                         ret = false;
1850                 }
1851         } else {
1852                 if (!test_key(p, tctx, &handle, 0, false)) {
1853                         ret = false;
1854                 }
1855         }
1856
1857         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1858
1859         return ret;
1860 }
1861
1862 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
1863 {
1864         struct torture_rpc_tcase *tcase;
1865         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
1866         struct torture_test *test;
1867
1868         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
1869                                                   &ndr_table_winreg);
1870
1871         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
1872                                           test_InitiateSystemShutdown);
1873         test->dangerous = true;
1874
1875         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
1876                                           test_InitiateSystemShutdownEx);
1877         test->dangerous = true;
1878
1879         /* Basic tests without security descriptors */
1880         torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
1881                                       test_Open,
1882                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1883         torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
1884                                       test_Open,
1885                                       (winreg_open_fn)dcerpc_winreg_OpenHKU);
1886         torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
1887                                       test_Open,
1888                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1889         torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
1890                                       test_Open,
1891                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1892
1893         /* Security descriptor tests */
1894         torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
1895                                       test_Open_Security,
1896                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1897         torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
1898                                       test_Open_Security,
1899                                       (winreg_open_fn)dcerpc_winreg_OpenHKU);
1900         torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
1901                                       test_Open_Security,
1902                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1903         torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
1904                                       test_Open_Security,
1905                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1906
1907         return suite;
1908 }