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