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