s3-torture: Improve the winreg deletekey torture comments.
[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,2010
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/torture_rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
30
31 #define TEST_KEY_BASE "winreg_torture_test"
32 #define TEST_KEY1 "spottyfoot"
33 #define TEST_KEY2 "with a SD (#1)"
34 #define TEST_KEY3 "with a subkey"
35 #define TEST_KEY4 "sd_tests"
36 #define TEST_SUBKEY "subkey"
37 #define TEST_SUBKEY_SD  "subkey_sd"
38 #define TEST_SUBSUBKEY_SD "subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
40 #define TEST_KEY_VOLATILE "torture_volatile_key"
41 #define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
42 #define TEST_KEY_SYMLINK "torture_symlink_key"
43 #define TEST_KEY_SYMLINK_DEST "torture_symlink_dest"
44
45 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
46
47 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
48 {
49         name->string = s;
50 }
51
52 static void init_winreg_String(struct winreg_String *name, const char *s)
53 {
54         name->name = s;
55         if (s) {
56                 name->name_len = 2 * (strlen_m(s) + 1);
57                 name->name_size = name->name_len;
58         } else {
59                 name->name_len = 0;
60                 name->name_size = 0;
61         }
62 }
63
64 static bool test_GetVersion(struct dcerpc_binding_handle *b,
65                             struct torture_context *tctx,
66                             struct policy_handle *handle)
67 {
68         struct winreg_GetVersion r;
69         uint32_t v;
70
71         torture_comment(tctx, "Testing GetVersion\n");
72
73         ZERO_STRUCT(r);
74         r.in.handle = handle;
75         r.out.version = &v;
76
77         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
78                                    "GetVersion failed");
79
80         torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
81
82         return true;
83 }
84
85 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
86                                       struct torture_context *tctx,
87                                       struct policy_handle *handle)
88 {
89         struct winreg_NotifyChangeKeyValue r;
90
91         ZERO_STRUCT(r);
92         r.in.handle = handle;
93         r.in.watch_subtree = true;
94         r.in.notify_filter = 0;
95         r.in.unknown = r.in.unknown2 = 0;
96         init_winreg_String(&r.in.string1, NULL);
97         init_winreg_String(&r.in.string2, NULL);
98
99         torture_assert_ntstatus_ok(tctx,
100                                    dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
101                                    "NotifyChangeKeyValue failed");
102
103         if (!W_ERROR_IS_OK(r.out.result)) {
104                 torture_comment(tctx,
105                                 "NotifyChangeKeyValue failed - %s - not considering\n",
106                                 win_errstr(r.out.result));
107                 return true;
108         }
109
110         return true;
111 }
112
113 static bool test_CreateKey_opts(struct torture_context *tctx,
114                                 struct dcerpc_binding_handle *b,
115                                 struct policy_handle *handle,
116                                 const char *name,
117                                 const char *kclass,
118                                 uint32_t options,
119                                 uint32_t access_mask,
120                                 struct winreg_SecBuf *secdesc,
121                                 WERROR expected_result,
122                                 enum winreg_CreateAction *action_taken_p,
123                                 struct policy_handle *new_handle_p)
124 {
125         struct winreg_CreateKey r;
126         struct policy_handle newhandle;
127         enum winreg_CreateAction action_taken = 0;
128
129         torture_comment(tctx, "Testing CreateKey(%s)\n", name);
130
131         ZERO_STRUCT(r);
132         r.in.handle = handle;
133         init_winreg_String(&r.in.name, name);
134         init_winreg_String(&r.in.keyclass, kclass);
135         r.in.options = options;
136         r.in.access_mask = access_mask;
137         r.in.action_taken = &action_taken;
138         r.in.secdesc = secdesc;
139         r.out.new_handle = &newhandle;
140         r.out.action_taken = &action_taken;
141
142         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
143                                    "CreateKey failed");
144
145         torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
146
147         if (new_handle_p) {
148                 *new_handle_p = newhandle;
149         }
150         if (action_taken_p) {
151                 *action_taken_p = *r.out.action_taken;
152         }
153
154         return true;
155 }
156
157 static bool test_CreateKey(struct dcerpc_binding_handle *b,
158                            struct torture_context *tctx,
159                            struct policy_handle *handle, const char *name,
160                            const char *kclass)
161 {
162         return test_CreateKey_opts(tctx, b, handle, name, kclass,
163                                    REG_OPTION_NON_VOLATILE,
164                                    SEC_FLAG_MAXIMUM_ALLOWED,
165                                    NULL, /* secdesc */
166                                    WERR_OK,
167                                    NULL, /* action_taken */
168                                    NULL /* new_handle */);
169 }
170
171 /*
172   createkey testing with a SD
173 */
174 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
175                               struct torture_context *tctx,
176                               struct policy_handle *handle, const char *name,
177                               const char *kclass,
178                               struct policy_handle *newhandle)
179 {
180         struct winreg_CreateKey r;
181         enum winreg_CreateAction action_taken = 0;
182         struct security_descriptor *sd;
183         DATA_BLOB sdblob;
184         struct winreg_SecBuf secbuf;
185
186         sd = security_descriptor_dacl_create(tctx,
187                                         0,
188                                         NULL, NULL,
189                                         SID_NT_AUTHENTICATED_USERS,
190                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
191                                         SEC_GENERIC_ALL,
192                                         SEC_ACE_FLAG_OBJECT_INHERIT |
193                                         SEC_ACE_FLAG_CONTAINER_INHERIT,
194                                         NULL);
195
196         torture_assert_ndr_success(tctx,
197                 ndr_push_struct_blob(&sdblob, tctx, sd,
198                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
199                                      "Failed to push security_descriptor ?!\n");
200
201         secbuf.sd.data = sdblob.data;
202         secbuf.sd.len = sdblob.length;
203         secbuf.sd.size = sdblob.length;
204         secbuf.length = sdblob.length-10;
205         secbuf.inherit = 0;
206
207         ZERO_STRUCT(r);
208         r.in.handle = handle;
209         r.out.new_handle = newhandle;
210         init_winreg_String(&r.in.name, name);
211         init_winreg_String(&r.in.keyclass, kclass);
212         r.in.options = 0x0;
213         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214         r.in.action_taken = r.out.action_taken = &action_taken;
215         r.in.secdesc = &secbuf;
216
217         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
218                                    "CreateKey with sd failed");
219
220         torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
221
222         return true;
223 }
224
225 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
226                                  struct torture_context *tctx,
227                                  struct policy_handle *handle,
228                                  uint32_t *sec_info_ptr,
229                                  WERROR get_werr,
230                                  struct security_descriptor **sd_out)
231 {
232         struct winreg_GetKeySecurity r;
233         struct security_descriptor *sd = NULL;
234         uint32_t sec_info;
235         DATA_BLOB sdblob;
236         struct dcerpc_binding_handle *b = p->binding_handle;
237
238         if (sec_info_ptr) {
239                 sec_info = *sec_info_ptr;
240         } else {
241                 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
242         }
243
244         ZERO_STRUCT(r);
245
246         r.in.handle = handle;
247         r.in.sec_info = sec_info;
248         r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
249         r.in.sd->size = 0x1000;
250
251         torture_assert_ntstatus_ok(tctx,
252                                    dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
253                                    "GetKeySecurity failed");
254
255         torture_assert_werr_equal(tctx, r.out.result, get_werr,
256                                   "GetKeySecurity failed");
257
258         sdblob.data = r.out.sd->data;
259         sdblob.length = r.out.sd->len;
260
261         sd = talloc_zero(tctx, struct security_descriptor);
262
263         torture_assert_ndr_success(tctx,
264                 ndr_pull_struct_blob(&sdblob, tctx, sd,
265                                      (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
266                                      "pull_security_descriptor failed");
267
268         if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
269                 NDR_PRINT_DEBUG(security_descriptor, sd);
270         }
271
272         if (sd_out) {
273                 *sd_out = sd;
274         } else {
275                 talloc_free(sd);
276         }
277
278         return true;
279 }
280
281 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
282                                 struct torture_context *tctx,
283                                 struct policy_handle *handle,
284                                 struct security_descriptor **sd_out)
285 {
286         return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
287 }
288
289 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
290                                  struct torture_context *tctx,
291                                  struct policy_handle *handle,
292                                  uint32_t *sec_info_ptr,
293                                  struct security_descriptor *sd,
294                                  WERROR werr)
295 {
296         struct winreg_SetKeySecurity r;
297         struct KeySecurityData *sdata = NULL;
298         DATA_BLOB sdblob;
299         uint32_t sec_info;
300         struct dcerpc_binding_handle *b = p->binding_handle;
301
302         ZERO_STRUCT(r);
303
304         if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
305                 NDR_PRINT_DEBUG(security_descriptor, sd);
306         }
307
308         torture_assert_ndr_success(tctx,
309                 ndr_push_struct_blob(&sdblob, tctx, sd,
310                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
311                                      "push_security_descriptor failed");
312
313         sdata = talloc_zero(tctx, struct KeySecurityData);
314         sdata->data = sdblob.data;
315         sdata->size = sdblob.length;
316         sdata->len = sdblob.length;
317
318         if (sec_info_ptr) {
319                 sec_info = *sec_info_ptr;
320         } else {
321                 sec_info = SECINFO_UNPROTECTED_SACL |
322                            SECINFO_UNPROTECTED_DACL;
323                 if (sd->owner_sid) {
324                         sec_info |= SECINFO_OWNER;
325                 }
326                 if (sd->group_sid) {
327                         sec_info |= SECINFO_GROUP;
328                 }
329                 if (sd->sacl) {
330                         sec_info |= SECINFO_SACL;
331                 }
332                 if (sd->dacl) {
333                         sec_info |= SECINFO_DACL;
334                 }
335         }
336
337         r.in.handle = handle;
338         r.in.sec_info = sec_info;
339         r.in.sd = sdata;
340
341         torture_assert_ntstatus_ok(tctx,
342                                    dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
343                                    "SetKeySecurity failed");
344
345         torture_assert_werr_equal(tctx, r.out.result, werr,
346                                   "SetKeySecurity failed");
347
348         return true;
349 }
350
351 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
352                                 struct torture_context *tctx,
353                                 struct policy_handle *handle,
354                                 struct security_descriptor *sd)
355 {
356         return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
357 }
358
359 static bool test_CloseKey(struct dcerpc_binding_handle *b,
360                           struct torture_context *tctx,
361                           struct policy_handle *handle)
362 {
363         struct winreg_CloseKey r;
364
365         ZERO_STRUCT(r);
366         r.in.handle = r.out.handle = handle;
367
368         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
369                                    "CloseKey failed");
370
371         torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
372
373         return true;
374 }
375
376 static bool test_FlushKey(struct dcerpc_binding_handle *b,
377                           struct torture_context *tctx,
378                           struct policy_handle *handle)
379 {
380         struct winreg_FlushKey r;
381
382         ZERO_STRUCT(r);
383         r.in.handle = handle;
384
385         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
386                                    "FlushKey failed");
387
388         torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
389
390         return true;
391 }
392
393 static bool test_OpenKey_opts(struct torture_context *tctx,
394                               struct dcerpc_binding_handle *b,
395                               struct policy_handle *hive_handle,
396                               const char *keyname,
397                               uint32_t options,
398                               uint32_t access_mask,
399                               struct policy_handle *key_handle,
400                               WERROR expected_result)
401 {
402         struct winreg_OpenKey r;
403
404         ZERO_STRUCT(r);
405         r.in.parent_handle = hive_handle;
406         init_winreg_String(&r.in.keyname, keyname);
407         r.in.options = options;
408         r.in.access_mask = access_mask;
409         r.out.handle = key_handle;
410
411         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
412                                    "OpenKey failed");
413
414         torture_assert_werr_equal(tctx, r.out.result, expected_result,
415                                   "OpenKey failed");
416
417         return true;
418 }
419
420 static bool test_OpenKey(struct dcerpc_binding_handle *b,
421                          struct torture_context *tctx,
422                          struct policy_handle *hive_handle,
423                          const char *keyname, struct policy_handle *key_handle)
424 {
425         return test_OpenKey_opts(tctx, b, hive_handle, keyname,
426                                  REG_OPTION_NON_VOLATILE,
427                                  SEC_FLAG_MAXIMUM_ALLOWED,
428                                  key_handle,
429                                  WERR_OK);
430 }
431
432 static bool test_Cleanup(struct dcerpc_binding_handle *b,
433                          struct torture_context *tctx,
434                          struct policy_handle *handle, const char *key)
435 {
436         struct winreg_DeleteKey r;
437
438         ZERO_STRUCT(r);
439         r.in.handle = handle;
440
441         init_winreg_String(&r.in.key, key);
442         dcerpc_winreg_DeleteKey_r(b, tctx, &r);
443
444         return true;
445 }
446
447 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
448                                            struct torture_context *tctx,
449                                            struct policy_handle *handle,
450                                            WERROR get_werr,
451                                            WERROR set_werr)
452 {
453         struct security_descriptor *sd = NULL;
454
455         if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
456                 return false;
457         }
458
459         if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
460                 return false;
461         }
462
463         return true;
464 }
465
466 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
467                                     struct torture_context *tctx,
468                                     struct policy_handle *handle,
469                                     const char *key)
470 {
471         struct policy_handle new_handle;
472         bool ret = true;
473         struct dcerpc_binding_handle *b = p->binding_handle;
474
475         torture_comment(tctx, "SecurityDescriptor get & set\n");
476
477         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
478                 return false;
479         }
480
481         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
482                                             WERR_OK, WERR_OK)) {
483                 ret = false;
484         }
485
486         if (!test_CloseKey(b, tctx, &new_handle)) {
487                 return false;
488         }
489
490         return ret;
491 }
492
493 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
494                                      struct torture_context *tctx,
495                                      struct policy_handle *handle,
496                                      uint32_t access_mask,
497                                      const char *key,
498                                      WERROR open_werr,
499                                      WERROR get_werr,
500                                      WERROR set_werr)
501 {
502         struct policy_handle new_handle;
503         bool ret = true;
504         struct dcerpc_binding_handle *b = p->binding_handle;
505
506         torture_assert(tctx,
507                 test_OpenKey_opts(tctx, b, handle, key,
508                                   REG_OPTION_NON_VOLATILE,
509                                   access_mask,
510                                   &new_handle,
511                                   open_werr),
512                 "failed to open key");
513
514         if (!W_ERROR_IS_OK(open_werr)) {
515                 return true;
516         }
517
518         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
519                                             get_werr, set_werr)) {
520                 ret = false;
521         }
522
523         if (!test_CloseKey(b, tctx, &new_handle)) {
524                 return false;
525         }
526
527         return ret;
528 }
529
530 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
531                                       struct torture_context *tctx,
532                                       struct policy_handle *handle,
533                                       const struct dom_sid *sid)
534 {
535         struct security_descriptor *sd = NULL;
536         int i;
537
538         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
539                 return false;
540         }
541
542         if (!sd || !sd->dacl) {
543                 return false;
544         }
545
546         for (i = 0; i < sd->dacl->num_aces; i++) {
547                 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
548                         return true;
549                 }
550         }
551
552         return false;
553 }
554
555 static bool _test_dacl_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         struct dcerpc_binding_handle *b = p->binding_handle;
564
565         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
566                 return false;
567         }
568
569         ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
570
571         test_CloseKey(b, tctx, &new_handle);
572
573         return ret;
574 }
575
576 static bool test_sacl_trustee_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         int i;
583         uint32_t sec_info = SECINFO_SACL;
584
585         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
586                 return false;
587         }
588
589         if (!sd || !sd->sacl) {
590                 return false;
591         }
592
593         for (i = 0; i < sd->sacl->num_aces; i++) {
594                 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
595                         return true;
596                 }
597         }
598
599         return false;
600 }
601
602 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
603                                        struct torture_context *tctx,
604                                        struct policy_handle *handle,
605                                        const char *key,
606                                        const struct dom_sid *sid)
607 {
608         struct policy_handle new_handle;
609         bool ret = true;
610         struct dcerpc_binding_handle *b = p->binding_handle;
611
612         torture_assert(tctx,
613                 test_OpenKey_opts(tctx, b, handle, key,
614                                   REG_OPTION_NON_VOLATILE,
615                                   SEC_FLAG_SYSTEM_SECURITY,
616                                   &new_handle,
617                                   WERR_OK),
618                 "failed to open key");
619
620         ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
621
622         test_CloseKey(b, tctx, &new_handle);
623
624         return ret;
625 }
626
627 static bool test_owner_present(struct dcerpc_pipe *p,
628                                struct torture_context *tctx,
629                                struct policy_handle *handle,
630                                const struct dom_sid *sid)
631 {
632         struct security_descriptor *sd = NULL;
633         uint32_t sec_info = SECINFO_OWNER;
634
635         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
636                 return false;
637         }
638
639         if (!sd || !sd->owner_sid) {
640                 return false;
641         }
642
643         return dom_sid_equal(sd->owner_sid, sid);
644 }
645
646 static bool _test_owner_present(struct dcerpc_pipe *p,
647                                 struct torture_context *tctx,
648                                 struct policy_handle *handle,
649                                 const char *key,
650                                 const struct dom_sid *sid)
651 {
652         struct policy_handle new_handle;
653         bool ret = true;
654         struct dcerpc_binding_handle *b = p->binding_handle;
655
656         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
657                 return false;
658         }
659
660         ret = test_owner_present(p, tctx, &new_handle, sid);
661
662         test_CloseKey(b, tctx, &new_handle);
663
664         return ret;
665 }
666
667 static bool test_group_present(struct dcerpc_pipe *p,
668                                struct torture_context *tctx,
669                                struct policy_handle *handle,
670                                const struct dom_sid *sid)
671 {
672         struct security_descriptor *sd = NULL;
673         uint32_t sec_info = SECINFO_GROUP;
674
675         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
676                 return false;
677         }
678
679         if (!sd || !sd->group_sid) {
680                 return false;
681         }
682
683         return dom_sid_equal(sd->group_sid, sid);
684 }
685
686 static bool _test_group_present(struct dcerpc_pipe *p,
687                                 struct torture_context *tctx,
688                                 struct policy_handle *handle,
689                                 const char *key,
690                                 const struct dom_sid *sid)
691 {
692         struct policy_handle new_handle;
693         bool ret = true;
694         struct dcerpc_binding_handle *b = p->binding_handle;
695
696         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
697                 return false;
698         }
699
700         ret = test_group_present(p, tctx, &new_handle, sid);
701
702         test_CloseKey(b, tctx, &new_handle);
703
704         return ret;
705 }
706
707 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
708                                             struct torture_context *tctx,
709                                             struct policy_handle *handle,
710                                             const struct dom_sid *sid,
711                                             uint8_t flags)
712 {
713         struct security_descriptor *sd = NULL;
714         int i;
715
716         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
717                 return false;
718         }
719
720         if (!sd || !sd->dacl) {
721                 return false;
722         }
723
724         for (i = 0; i < sd->dacl->num_aces; i++) {
725                 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
726                     (sd->dacl->aces[i].flags == flags)) {
727                         return true;
728                 }
729         }
730
731         return false;
732 }
733
734 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
735                                   struct torture_context *tctx,
736                                   struct policy_handle *handle,
737                                   const struct security_ace *ace)
738 {
739         struct security_descriptor *sd = NULL;
740         int i;
741
742         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
743                 return false;
744         }
745
746         if (!sd || !sd->dacl) {
747                 return false;
748         }
749
750         for (i = 0; i < sd->dacl->num_aces; i++) {
751                 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
752                         return true;
753                 }
754         }
755
756         return false;
757 }
758
759 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
760                                  struct torture_context *tctx,
761                                  struct policy_handle *handle,
762                                  const char *key,
763                                  struct security_descriptor *sd)
764 {
765         struct policy_handle new_handle;
766         bool ret = true;
767         struct dcerpc_binding_handle *b = p->binding_handle;
768
769         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
770                 return false;
771         }
772
773         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
774                 ret = false;
775         }
776
777         if (!test_CloseKey(b, tctx, &new_handle)) {
778                 ret = false;
779         }
780
781         return ret;
782 }
783
784 static bool test_BackupSecurity(struct dcerpc_pipe *p,
785                                 struct torture_context *tctx,
786                                 struct policy_handle *handle,
787                                 const char *key,
788                                 struct security_descriptor **sd)
789 {
790         struct policy_handle new_handle;
791         bool ret = true;
792         struct dcerpc_binding_handle *b = p->binding_handle;
793
794         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
795                 return false;
796         }
797
798         if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
799                 ret = false;
800         }
801
802         if (!test_CloseKey(b, tctx, &new_handle)) {
803                 ret = false;
804         }
805
806         return ret;
807 }
808
809 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
810                                                struct torture_context *tctx,
811                                                struct policy_handle *handle,
812                                                const char *key)
813 {
814         /* get sd
815            add ace SEC_ACE_FLAG_CONTAINER_INHERIT
816            set sd
817            get sd
818            check ace
819            add subkey
820            get sd
821            check ace
822            add subsubkey
823            get sd
824            check ace
825            del subsubkey
826            del subkey
827            reset sd
828         */
829
830         struct security_descriptor *sd = NULL;
831         struct security_descriptor *sd_orig = NULL;
832         struct security_ace *ace = NULL;
833         struct policy_handle new_handle;
834         bool ret = true;
835         struct dcerpc_binding_handle *b = p->binding_handle;
836         const char *test_subkey_sd;
837         const char *test_subsubkey_sd;
838
839         torture_comment(tctx, "SecurityDescriptor inheritance\n");
840
841         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
842                 return false;
843         }
844
845         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
846                 return false;
847         }
848
849         sd_orig = security_descriptor_copy(tctx, sd);
850         if (sd_orig == NULL) {
851                 return false;
852         }
853
854         ace = security_ace_create(tctx,
855                                   TEST_SID,
856                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
857                                   SEC_STD_REQUIRED,
858                                   SEC_ACE_FLAG_CONTAINER_INHERIT);
859
860         torture_assert_ntstatus_ok(tctx,
861                 security_descriptor_dacl_add(sd, ace),
862                 "failed to add ace");
863
864         /* FIXME: add further tests for these flags */
865         sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
866                     SEC_DESC_SACL_AUTO_INHERITED;
867
868         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
869                 return false;
870         }
871
872         torture_assert(tctx,
873                 test_dacl_ace_present(p, tctx, &new_handle, ace),
874                 "new ACE not present!");
875
876         if (!test_CloseKey(b, tctx, &new_handle)) {
877                 return false;
878         }
879
880         test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
881
882         if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
883                 ret = false;
884                 goto out;
885         }
886
887         if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
888                 ret = false;
889                 goto out;
890         }
891
892         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
893                 torture_comment(tctx, "inherited ACE not present!\n");
894                 ret = false;
895                 goto out;
896         }
897
898         test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
899
900         test_CloseKey(b, tctx, &new_handle);
901         if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
902                 ret = false;
903                 goto out;
904         }
905
906         if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
907                 ret = false;
908                 goto out;
909         }
910
911         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
912                 torture_comment(tctx, "inherited ACE not present!\n");
913                 ret = false;
914                 goto out;
915         }
916
917  out:
918         test_CloseKey(b, tctx, &new_handle);
919         test_Cleanup(b, tctx, handle, test_subkey_sd);
920         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
921
922         return ret;
923 }
924
925 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
926                                                     struct torture_context *tctx,
927                                                     struct policy_handle *handle,
928                                                     const char *key)
929 {
930         /* get sd
931            add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
932            set sd
933            add subkey/subkey
934            get sd
935            check ace
936            get sd from subkey
937            check ace
938            del subkey/subkey
939            del subkey
940            reset sd
941         */
942
943         struct security_descriptor *sd = NULL;
944         struct security_descriptor *sd_orig = NULL;
945         struct security_ace *ace = NULL;
946         struct policy_handle new_handle;
947         struct dom_sid *sid = NULL;
948         bool ret = true;
949         uint8_t ace_flags = 0x0;
950         struct dcerpc_binding_handle *b = p->binding_handle;
951         const char *test_subkey_sd;
952         const char *test_subsubkey_sd;
953
954         torture_comment(tctx, "SecurityDescriptor inheritance block\n");
955
956         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
957                 return false;
958         }
959
960         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
961                 return false;
962         }
963
964         sd_orig = security_descriptor_copy(tctx, sd);
965         if (sd_orig == NULL) {
966                 return false;
967         }
968
969         ace = security_ace_create(tctx,
970                                   TEST_SID,
971                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
972                                   SEC_STD_REQUIRED,
973                                   SEC_ACE_FLAG_CONTAINER_INHERIT |
974                                   SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
975
976         torture_assert_ntstatus_ok(tctx,
977                 security_descriptor_dacl_add(sd, ace),
978                 "failed to add ace");
979
980         if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
981                 return false;
982         }
983
984         torture_assert(tctx,
985                 test_dacl_ace_present(p, tctx, &new_handle, ace),
986                 "new ACE not present!");
987
988         if (!test_CloseKey(b, tctx, &new_handle)) {
989                 return false;
990         }
991
992         test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
993         test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
994
995         if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
996                 return false;
997         }
998
999         if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
1000                 ret = false;
1001                 goto out;
1002         }
1003
1004         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1005                 torture_comment(tctx, "inherited ACE present but should not!\n");
1006                 ret = false;
1007                 goto out;
1008         }
1009
1010         sid = dom_sid_parse_talloc(tctx, TEST_SID);
1011         if (sid == NULL) {
1012                 return false;
1013         }
1014
1015         if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1016                 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1017                 ret = false;
1018                 goto out;
1019         }
1020
1021         test_CloseKey(b, tctx, &new_handle);
1022
1023         if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1024                 ret = false;
1025                 goto out;
1026         }
1027
1028         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1029                 torture_comment(tctx, "inherited ACE present but should not!\n");
1030                 ret = false;
1031                 goto out;
1032         }
1033
1034         if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1035                 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1036                         ace_flags);
1037                 ret = false;
1038                 goto out;
1039         }
1040
1041  out:
1042         test_CloseKey(b, tctx, &new_handle);
1043         test_Cleanup(b, tctx, handle, test_subkey_sd);
1044         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1045
1046         return ret;
1047 }
1048
1049 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1050                                           struct torture_context *tctx,
1051                                           struct policy_handle *handle,
1052                                           const char *key)
1053 {
1054         bool ret = true;
1055         int i;
1056
1057         struct winreg_mask_result_table {
1058                 uint32_t access_mask;
1059                 WERROR open_werr;
1060                 WERROR get_werr;
1061                 WERROR set_werr;
1062         } sd_mask_tests[] = {
1063                 { 0,
1064                         WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1065                 { SEC_FLAG_MAXIMUM_ALLOWED,
1066                         WERR_OK, WERR_OK, WERR_OK },
1067                 { SEC_STD_WRITE_DAC,
1068                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1069                 { SEC_FLAG_SYSTEM_SECURITY,
1070                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1071         };
1072
1073         /* FIXME: before this test can ever run successfully we need a way to
1074          * correctly read a NULL security_descritpor in ndr, get the required
1075          * length, requery, etc.
1076          */
1077
1078         return true;
1079
1080         for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1081
1082                 torture_comment(tctx,
1083                                 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1084                                 sd_mask_tests[i].access_mask);
1085                 torture_comment(tctx,
1086                                 "expecting: open %s, get: %s, set: %s\n",
1087                                 win_errstr(sd_mask_tests[i].open_werr),
1088                                 win_errstr(sd_mask_tests[i].get_werr),
1089                                 win_errstr(sd_mask_tests[i].set_werr));
1090
1091                 if (_test_SecurityDescriptor(p, tctx, handle,
1092                                              sd_mask_tests[i].access_mask, key,
1093                                              sd_mask_tests[i].open_werr,
1094                                              sd_mask_tests[i].get_werr,
1095                                              sd_mask_tests[i].set_werr)) {
1096                         ret = false;
1097                 }
1098         }
1099
1100         return ret;
1101 }
1102
1103 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1104                                   struct torture_context *,
1105                                   struct policy_handle *,
1106                                   const char *,
1107                                   const struct dom_sid *);
1108
1109 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1110                                                struct torture_context *tctx,
1111                                                struct policy_handle *handle,
1112                                                const char *key,
1113                                                const char *test,
1114                                                uint32_t access_mask,
1115                                                uint32_t sec_info,
1116                                                struct security_descriptor *sd,
1117                                                WERROR set_werr,
1118                                                bool expect_present,
1119                                                bool (*fn) (struct dcerpc_pipe *,
1120                                                            struct torture_context *,
1121                                                            struct policy_handle *,
1122                                                            const char *,
1123                                                            const struct dom_sid *),
1124                                                const struct dom_sid *sid)
1125 {
1126         struct policy_handle new_handle;
1127         struct dcerpc_binding_handle *b = p->binding_handle;
1128
1129         torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1130                         "0x%08x, access_mask: 0x%08x\n",
1131                         test, sec_info, access_mask);
1132
1133         torture_assert(tctx,
1134                 test_OpenKey_opts(tctx, b, handle, key,
1135                                   REG_OPTION_NON_VOLATILE,
1136                                   access_mask,
1137                                   &new_handle,
1138                                   WERR_OK),
1139                 "failed to open key");
1140
1141         if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1142                                   sd,
1143                                   set_werr)) {
1144                 torture_warning(tctx,
1145                                 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1146                                 sec_info);
1147                 smb_panic("");
1148                 test_CloseKey(b, tctx, &new_handle);
1149                 return false;
1150         }
1151
1152         test_CloseKey(b, tctx, &new_handle);
1153
1154         if (W_ERROR_IS_OK(set_werr)) {
1155                 bool present;
1156                 present = fn(p, tctx, handle, key, sid);
1157                 if ((expect_present) && (!present)) {
1158                         torture_warning(tctx,
1159                                         "%s sid is not present!\n",
1160                                         test);
1161                         return false;
1162                 }
1163                 if ((!expect_present) && (present)) {
1164                         torture_warning(tctx,
1165                                         "%s sid is present but not expected!\n",
1166                                         test);
1167                         return false;
1168                 }
1169         }
1170
1171         return true;
1172 }
1173
1174 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1175                                             struct torture_context *tctx,
1176                                             struct policy_handle *handle,
1177                                             const char *key)
1178 {
1179         struct security_descriptor *sd_orig = NULL;
1180         struct dom_sid *sid = NULL;
1181         bool ret = true;
1182         int i, a;
1183
1184         struct security_descriptor *sd_owner =
1185                 security_descriptor_dacl_create(tctx,
1186                                                 0,
1187                                                 TEST_SID, NULL, NULL);
1188
1189         struct security_descriptor *sd_group =
1190                 security_descriptor_dacl_create(tctx,
1191                                                 0,
1192                                                 NULL, TEST_SID, NULL);
1193
1194         struct security_descriptor *sd_dacl =
1195                 security_descriptor_dacl_create(tctx,
1196                                                 0,
1197                                                 NULL, NULL,
1198                                                 TEST_SID,
1199                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1200                                                 SEC_GENERIC_ALL,
1201                                                 0,
1202                                                 SID_NT_AUTHENTICATED_USERS,
1203                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1204                                                 SEC_GENERIC_ALL,
1205                                                 0,
1206                                                 NULL);
1207
1208         struct security_descriptor *sd_sacl =
1209                 security_descriptor_sacl_create(tctx,
1210                                                 0,
1211                                                 NULL, NULL,
1212                                                 TEST_SID,
1213                                                 SEC_ACE_TYPE_SYSTEM_AUDIT,
1214                                                 SEC_GENERIC_ALL,
1215                                                 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1216                                                 NULL);
1217
1218         struct winreg_secinfo_table {
1219                 struct security_descriptor *sd;
1220                 uint32_t sec_info;
1221                 WERROR set_werr;
1222                 bool sid_present;
1223                 secinfo_verify_fn fn;
1224         };
1225
1226         struct winreg_secinfo_table sec_info_owner_tests[] = {
1227                 { sd_owner, 0, WERR_OK,
1228                         false, (secinfo_verify_fn)_test_owner_present },
1229                 { sd_owner, SECINFO_OWNER, WERR_OK,
1230                         true, (secinfo_verify_fn)_test_owner_present },
1231                 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1232                 { sd_owner, SECINFO_DACL, WERR_OK,
1233                         true, (secinfo_verify_fn)_test_owner_present },
1234                 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1235         };
1236
1237         uint32_t sd_owner_good_access_masks[] = {
1238                 SEC_FLAG_MAXIMUM_ALLOWED,
1239                 /* SEC_STD_WRITE_OWNER, */
1240         };
1241
1242         struct winreg_secinfo_table sec_info_group_tests[] = {
1243                 { sd_group, 0, WERR_OK,
1244                         false, (secinfo_verify_fn)_test_group_present },
1245                 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1246                 { sd_group, SECINFO_GROUP, WERR_OK,
1247                         true, (secinfo_verify_fn)_test_group_present },
1248                 { sd_group, SECINFO_DACL, WERR_OK,
1249                         true, (secinfo_verify_fn)_test_group_present },
1250                 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1251         };
1252
1253         uint32_t sd_group_good_access_masks[] = {
1254                 SEC_FLAG_MAXIMUM_ALLOWED,
1255         };
1256
1257         struct winreg_secinfo_table sec_info_dacl_tests[] = {
1258                 { sd_dacl, 0, WERR_OK,
1259                         false, (secinfo_verify_fn)_test_dacl_trustee_present },
1260                 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1261                 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1262                 { sd_dacl, SECINFO_DACL, WERR_OK,
1263                         true, (secinfo_verify_fn)_test_dacl_trustee_present },
1264                 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1265         };
1266
1267         uint32_t sd_dacl_good_access_masks[] = {
1268                 SEC_FLAG_MAXIMUM_ALLOWED,
1269                 SEC_STD_WRITE_DAC,
1270         };
1271
1272         struct winreg_secinfo_table sec_info_sacl_tests[] = {
1273                 { sd_sacl, 0, WERR_OK,
1274                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1275                 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1276                 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1277                 { sd_sacl, SECINFO_DACL, WERR_OK,
1278                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1279                 { sd_sacl, SECINFO_SACL, WERR_OK,
1280                         true, (secinfo_verify_fn)_test_sacl_trustee_present },
1281         };
1282
1283         uint32_t sd_sacl_good_access_masks[] = {
1284                 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1285                 /* SEC_FLAG_SYSTEM_SECURITY, */
1286         };
1287
1288         sid = dom_sid_parse_talloc(tctx, TEST_SID);
1289         if (sid == NULL) {
1290                 return false;
1291         }
1292
1293         if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1294                 return false;
1295         }
1296
1297         /* OWNER */
1298
1299         for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1300
1301                 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1302
1303                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1304                                         key,
1305                                         "OWNER",
1306                                         sd_owner_good_access_masks[a],
1307                                         sec_info_owner_tests[i].sec_info,
1308                                         sec_info_owner_tests[i].sd,
1309                                         sec_info_owner_tests[i].set_werr,
1310                                         sec_info_owner_tests[i].sid_present,
1311                                         sec_info_owner_tests[i].fn,
1312                                         sid))
1313                         {
1314                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1315                                 ret = false;
1316                                 goto out;
1317                         }
1318                 }
1319         }
1320
1321         /* GROUP */
1322
1323         for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1324
1325                 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1326
1327                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1328                                         key,
1329                                         "GROUP",
1330                                         sd_group_good_access_masks[a],
1331                                         sec_info_group_tests[i].sec_info,
1332                                         sec_info_group_tests[i].sd,
1333                                         sec_info_group_tests[i].set_werr,
1334                                         sec_info_group_tests[i].sid_present,
1335                                         sec_info_group_tests[i].fn,
1336                                         sid))
1337                         {
1338                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1339                                 ret = false;
1340                                 goto out;
1341                         }
1342                 }
1343         }
1344
1345         /* DACL */
1346
1347         for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1348
1349                 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1350
1351                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1352                                         key,
1353                                         "DACL",
1354                                         sd_dacl_good_access_masks[a],
1355                                         sec_info_dacl_tests[i].sec_info,
1356                                         sec_info_dacl_tests[i].sd,
1357                                         sec_info_dacl_tests[i].set_werr,
1358                                         sec_info_dacl_tests[i].sid_present,
1359                                         sec_info_dacl_tests[i].fn,
1360                                         sid))
1361                         {
1362                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1363                                 ret = false;
1364                                 goto out;
1365                         }
1366                 }
1367         }
1368
1369         /* SACL */
1370
1371         for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1372
1373                 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1374
1375                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1376                                         key,
1377                                         "SACL",
1378                                         sd_sacl_good_access_masks[a],
1379                                         sec_info_sacl_tests[i].sec_info,
1380                                         sec_info_sacl_tests[i].sd,
1381                                         sec_info_sacl_tests[i].set_werr,
1382                                         sec_info_sacl_tests[i].sid_present,
1383                                         sec_info_sacl_tests[i].fn,
1384                                         sid))
1385                         {
1386                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1387                                 ret = false;
1388                                 goto out;
1389                         }
1390                 }
1391         }
1392
1393  out:
1394         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1395
1396         return ret;
1397 }
1398
1399 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1400                                      struct torture_context *tctx,
1401                                      struct policy_handle *handle,
1402                                      const char *key)
1403 {
1404         bool ret = true;
1405
1406         if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1407                 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1408                 ret = false;
1409         }
1410
1411         if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1412                 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1413                 ret = false;
1414         }
1415
1416         if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1417                 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1418                 ret = false;
1419         }
1420
1421         if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1422                 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1423                 ret = false;
1424         }
1425
1426         if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1427                 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1428                 ret = false;
1429         }
1430
1431         return ret;
1432 }
1433
1434 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1435                                 struct torture_context *tctx,
1436                                 struct policy_handle *handle,
1437                                 const char *key,
1438                                 WERROR expected_result)
1439 {
1440         struct winreg_DeleteKey r;
1441
1442         torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1443
1444         r.in.handle = handle;
1445         init_winreg_String(&r.in.key, key);
1446
1447         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1448                 "Delete Key failed");
1449         torture_assert_werr_equal(tctx, r.out.result, expected_result,
1450                 "DeleteKey failed");
1451
1452         return true;
1453 }
1454
1455 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1456                            struct torture_context *tctx,
1457                            struct policy_handle *handle, const char *key)
1458 {
1459         return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1460 }
1461
1462 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1463                               struct torture_context *tctx,
1464                               struct policy_handle *handle,
1465                               char *kclass,
1466                               uint32_t *pmax_valnamelen,
1467                               uint32_t *pmax_valbufsize)
1468 {
1469         struct winreg_QueryInfoKey r;
1470         uint32_t num_subkeys, max_subkeylen, max_classlen,
1471                 num_values, max_valnamelen, max_valbufsize,
1472                 secdescsize;
1473         NTTIME last_changed_time;
1474
1475         ZERO_STRUCT(r);
1476         r.in.handle = handle;
1477         r.out.num_subkeys = &num_subkeys;
1478         r.out.max_subkeylen = &max_subkeylen;
1479         r.out.max_classlen = &max_classlen;
1480         r.out.num_values = &num_values;
1481         r.out.max_valnamelen = &max_valnamelen;
1482         r.out.max_valbufsize = &max_valbufsize;
1483         r.out.secdescsize = &secdescsize;
1484         r.out.last_changed_time = &last_changed_time;
1485
1486         r.out.classname = talloc(tctx, struct winreg_String);
1487
1488         r.in.classname = talloc(tctx, struct winreg_String);
1489         init_winreg_String(r.in.classname, kclass);
1490
1491         torture_assert_ntstatus_ok(tctx,
1492                                    dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1493                                    "QueryInfoKey failed");
1494
1495         torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1496
1497         if (pmax_valnamelen) {
1498                 *pmax_valnamelen = max_valnamelen;
1499         }
1500
1501         if (pmax_valbufsize) {
1502                 *pmax_valbufsize = max_valbufsize;
1503         }
1504
1505         return true;
1506 }
1507
1508 static bool test_SetValue(struct dcerpc_binding_handle *b,
1509                           struct torture_context *tctx,
1510                           struct policy_handle *handle,
1511                           const char *value_name,
1512                           enum winreg_Type type,
1513                           uint8_t *data,
1514                           uint32_t size)
1515 {
1516         struct winreg_SetValue r;
1517         struct winreg_String name;
1518
1519         torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1520                 value_name, str_regtype(type), size);
1521
1522         init_winreg_String(&name, value_name);
1523
1524         r.in.handle = handle;
1525         r.in.name = name;
1526         r.in.type = type;
1527         r.in.data = data;
1528         r.in.size = size;
1529
1530         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1531                 "winreg_SetValue failed");
1532         torture_assert_werr_ok(tctx, r.out.result,
1533                 "winreg_SetValue failed");
1534
1535         return true;
1536 }
1537
1538 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1539                              struct torture_context *tctx,
1540                              struct policy_handle *handle,
1541                              const char *value_name)
1542 {
1543         struct winreg_DeleteValue r;
1544         struct winreg_String value;
1545
1546         torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1547
1548         init_winreg_String(&value, value_name);
1549
1550         r.in.handle = handle;
1551         r.in.value = value;
1552
1553         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1554                 "winreg_DeleteValue failed");
1555         torture_assert_werr_ok(tctx, r.out.result,
1556                 "winreg_DeleteValue failed");
1557
1558         return true;
1559 }
1560
1561 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1562                      struct policy_handle *handle, int depth,
1563                      bool test_security);
1564
1565 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1566                          struct policy_handle *handle, int depth,
1567                          bool test_security)
1568 {
1569         struct winreg_EnumKey r;
1570         struct winreg_StringBuf kclass, name;
1571         NTSTATUS status;
1572         NTTIME t = 0;
1573         struct dcerpc_binding_handle *b = p->binding_handle;
1574
1575         kclass.name   = "";
1576         kclass.size   = 1024;
1577
1578         ZERO_STRUCT(r);
1579         r.in.handle = handle;
1580         r.in.enum_index = 0;
1581         r.in.name = &name;
1582         r.in.keyclass = &kclass;
1583         r.out.name = &name;
1584         r.in.last_changed_time = &t;
1585
1586         do {
1587                 name.name   = NULL;
1588                 name.size   = 1024;
1589
1590                 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1591
1592                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1593                         struct policy_handle key_handle;
1594
1595                         torture_comment(tctx, "EnumKey: %d: %s\n",
1596                                         r.in.enum_index,
1597                                         r.out.name->name);
1598
1599                         if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1600                                           &key_handle)) {
1601                         } else {
1602                                 test_key(p, tctx, &key_handle,
1603                                          depth + 1, test_security);
1604                         }
1605                 }
1606
1607                 r.in.enum_index++;
1608
1609         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1610
1611         torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1612
1613         if (!W_ERROR_IS_OK(r.out.result) &&
1614                 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1615                 torture_fail(tctx, "EnumKey failed");
1616         }
1617
1618         return true;
1619 }
1620
1621 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1622                                      struct torture_context *tctx,
1623                                      struct policy_handle *handle,
1624                                      const char *valuename)
1625 {
1626         struct winreg_QueryMultipleValues r;
1627         uint32_t bufsize=0;
1628
1629         ZERO_STRUCT(r);
1630
1631         r.in.key_handle = handle;
1632         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1633         r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1634         r.in.values_in[0].ve_valuename->name = valuename;
1635         /* size needs to be set manually for winreg_ValNameBuf */
1636         r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1637
1638         r.in.num_values = 1;
1639         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1640         *r.in.buffer_size = bufsize;
1641         do {
1642                 *r.in.buffer_size = bufsize;
1643                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1644                                                                *r.in.buffer_size);
1645
1646                 torture_assert_ntstatus_ok(tctx,
1647                         dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1648                         "QueryMultipleValues failed");
1649
1650                 talloc_free(r.in.buffer);
1651                 bufsize += 0x20;
1652         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1653
1654         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1655
1656         return true;
1657 }
1658
1659 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1660                                           struct torture_context *tctx,
1661                                           struct policy_handle *handle,
1662                                           uint32_t num_values,
1663                                           const char * const *valuenames,
1664                                           bool existing_value)
1665 {
1666         struct winreg_QueryMultipleValues r;
1667         uint32_t bufsize = 0;
1668         int i;
1669
1670         torture_comment(tctx, "Testing QueryMultipleValues\n");
1671
1672         ZERO_STRUCT(r);
1673
1674         r.in.key_handle = handle;
1675         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1676         r.in.buffer_size = r.out.buffer_size = &bufsize;
1677
1678         torture_assert_ntstatus_ok(tctx,
1679                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1680                 "QueryMultipleValues failed");
1681         torture_assert_werr_ok(tctx, r.out.result,
1682                 "QueryMultipleValues failed");
1683
1684         /* this test crashes w2k8 remote registry */
1685 #if 0
1686         r.in.num_values = num_values;
1687         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1688
1689         torture_assert_ntstatus_ok(tctx,
1690                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1691                 "QueryMultipleValues failed");
1692         torture_assert_werr_ok(tctx, r.out.result,
1693                 "QueryMultipleValues failed");
1694 #endif
1695         r.in.num_values = num_values;
1696         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1697         for (i=0; i < r.in.num_values; i++) {
1698                 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1699                 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1700                 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1701         }
1702
1703         torture_assert_ntstatus_ok(tctx,
1704                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1705                 "QueryMultipleValues failed");
1706         torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1707                 "QueryMultipleValues failed");
1708
1709         if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1710                 return true;
1711         }
1712
1713         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1714                 *r.in.buffer_size = 0xff;
1715                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1716
1717                 torture_assert_ntstatus_ok(tctx,
1718                         dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1719                         "QueryMultipleValues failed");
1720         }
1721
1722         torture_assert_werr_ok(tctx, r.out.result,
1723                 "QueryMultipleValues failed");
1724
1725         return true;
1726 }
1727
1728
1729 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1730                                            struct torture_context *tctx,
1731                                            struct policy_handle *handle,
1732                                            uint32_t num_values,
1733                                            const char * const *valuenames,
1734                                            bool existing_value)
1735 {
1736         struct winreg_QueryMultipleValues2 r;
1737         uint32_t offered = 0, needed;
1738         int i;
1739
1740         torture_comment(tctx, "Testing QueryMultipleValues2\n");
1741
1742         ZERO_STRUCT(r);
1743
1744         r.in.key_handle = handle;
1745         r.in.offered = &offered;
1746         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1747         r.out.needed = &needed;
1748
1749         torture_assert_ntstatus_ok(tctx,
1750                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1751                 "QueryMultipleValues2 failed");
1752         torture_assert_werr_ok(tctx, r.out.result,
1753                 "QueryMultipleValues2 failed");
1754
1755         /* this test crashes w2k8 remote registry */
1756 #if 0
1757         r.in.num_values = num_values;
1758         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1759
1760         torture_assert_ntstatus_ok(tctx,
1761                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1762                 "QueryMultipleValues2 failed");
1763         torture_assert_werr_ok(tctx, r.out.result,
1764                 "QueryMultipleValues2 failed");
1765 #endif
1766         r.in.num_values = num_values;
1767         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1768         for (i=0; i < r.in.num_values; i++) {
1769                 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1770                 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1771                 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1772         }
1773
1774         torture_assert_ntstatus_ok(tctx,
1775                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1776                 "QueryMultipleValues2 failed");
1777         torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1778                 "QueryMultipleValues2 failed");
1779
1780         if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1781                 return true;
1782         }
1783
1784         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1785                 *r.in.offered = *r.out.needed;
1786                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1787
1788                 torture_assert_ntstatus_ok(tctx,
1789                         dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1790                         "QueryMultipleValues2 failed");
1791         }
1792
1793         torture_assert_werr_ok(tctx, r.out.result,
1794                 "QueryMultipleValues2 failed");
1795
1796         return true;
1797 }
1798
1799 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1800                                       struct torture_context *tctx,
1801                                       struct policy_handle *handle,
1802                                       const char *valuename)
1803 {
1804         struct winreg_QueryMultipleValues2 r;
1805         uint32_t offered = 0, needed;
1806
1807         ZERO_STRUCT(r);
1808
1809         r.in.key_handle = handle;
1810         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1811         r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1812         r.in.values_in[0].ve_valuename->name = valuename;
1813         /* size needs to be set manually for winreg_ValNameBuf */
1814         r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1815
1816         r.in.num_values = 1;
1817         r.in.offered = &offered;
1818         r.out.needed = &needed;
1819
1820         torture_assert_ntstatus_ok(tctx,
1821                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1822                 "QueryMultipleValues2 failed");
1823         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1824                 *r.in.offered = *r.out.needed;
1825                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1826
1827                 torture_assert_ntstatus_ok(tctx,
1828                         dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1829                         "QueryMultipleValues2 failed");
1830         }
1831
1832         torture_assert_werr_ok(tctx, r.out.result,
1833                 "QueryMultipleValues2 failed");
1834
1835         return true;
1836 }
1837
1838 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1839                             struct torture_context *tctx,
1840                             struct policy_handle *handle,
1841                             const char *valuename)
1842 {
1843         struct winreg_QueryValue r;
1844         NTSTATUS status;
1845         enum winreg_Type zero_type = 0;
1846         uint32_t offered = 0xfff;
1847         uint32_t zero = 0;
1848
1849         ZERO_STRUCT(r);
1850         r.in.handle = handle;
1851         r.in.data = NULL;
1852         r.in.value_name = talloc_zero(tctx, struct winreg_String);
1853         r.in.value_name->name = valuename;
1854         r.in.type = &zero_type;
1855         r.in.data_size = &offered;
1856         r.in.data_length = &zero;
1857
1858         status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1859         if (NT_STATUS_IS_ERR(status)) {
1860                 torture_fail(tctx, "QueryValue failed");
1861         }
1862
1863         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1864
1865         return true;
1866 }
1867
1868 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1869                                  struct torture_context *tctx,
1870                                  struct policy_handle *handle,
1871                                  const char *valuename,
1872                                  bool existing_value)
1873 {
1874         struct winreg_QueryValue r;
1875         struct winreg_String value_name;
1876         enum winreg_Type type = REG_NONE;
1877         uint32_t data_size = 0;
1878         uint32_t real_data_size = 0;
1879         uint32_t data_length = 0;
1880         uint8_t *data = NULL;
1881         WERROR expected_error = WERR_BADFILE;
1882         const char *errmsg_nonexisting = "expected WERR_BADFILE for nonexisting value";
1883
1884         if (valuename == NULL) {
1885                 expected_error = WERR_INVALID_PARAM;
1886                 errmsg_nonexisting = "expected WERR_INVALID_PARAM for NULL valuename";
1887         }
1888
1889         ZERO_STRUCT(r);
1890
1891         init_winreg_String(&value_name, NULL);
1892
1893         torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1894
1895         r.in.handle = handle;
1896         r.in.value_name = &value_name;
1897
1898         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1899         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1900                 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1901
1902         init_winreg_String(&value_name, valuename);
1903         r.in.value_name = &value_name;
1904
1905         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1906                 "QueryValue failed");
1907         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1908                 "expected WERR_INVALID_PARAM for missing type length and size");
1909
1910         r.in.type = &type;
1911         r.out.type = &type;
1912         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1913                 "QueryValue failed");
1914         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1915                 "expected WERR_INVALID_PARAM for missing length and size");
1916
1917         r.in.data_length = &data_length;
1918         r.out.data_length = &data_length;
1919         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1920                 "QueryValue failed");
1921         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1922                 "expected WERR_INVALID_PARAM for missing size");
1923
1924         r.in.data_size = &data_size;
1925         r.out.data_size = &data_size;
1926         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1927                 "QueryValue failed");
1928         if (existing_value) {
1929                 torture_assert_werr_ok(tctx, r.out.result,
1930                         "QueryValue failed");
1931         } else {
1932                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1933                         errmsg_nonexisting);
1934         }
1935
1936         real_data_size = *r.out.data_size;
1937
1938         data = talloc_zero_array(tctx, uint8_t, 0);
1939         r.in.data = data;
1940         r.out.data = data;
1941         *r.in.data_size = 0;
1942         *r.out.data_size = 0;
1943         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1944                 "QueryValue failed");
1945         if (existing_value) {
1946                 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1947                         "expected WERR_MORE_DATA for query with too small buffer");
1948         } else {
1949                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1950                         errmsg_nonexisting);
1951         }
1952
1953         data = talloc_zero_array(tctx, uint8_t, real_data_size);
1954         r.in.data = data;
1955         r.out.data = data;
1956         r.in.data_size = &real_data_size;
1957         r.out.data_size = &real_data_size;
1958         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1959                 "QueryValue failed");
1960         if (existing_value) {
1961                 torture_assert_werr_ok(tctx, r.out.result,
1962                         "QueryValue failed");
1963         } else {
1964                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1965                         errmsg_nonexisting);
1966         }
1967
1968         return true;
1969 }
1970
1971 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1972                            struct torture_context *tctx,
1973                            struct policy_handle *handle, int max_valnamelen,
1974                            int max_valbufsize)
1975 {
1976         struct winreg_EnumValue r;
1977         enum winreg_Type type = 0;
1978         uint32_t size = max_valbufsize, zero = 0;
1979         bool ret = true;
1980         uint8_t *data = NULL;
1981         struct winreg_ValNameBuf name;
1982         char n = '\0';
1983
1984         ZERO_STRUCT(r);
1985         r.in.handle = handle;
1986         r.in.enum_index = 0;
1987         r.in.name = &name;
1988         r.out.name = &name;
1989         r.in.type = &type;
1990         r.in.length = &zero;
1991         r.in.size = &size;
1992
1993         do {
1994                 name.name = &n;
1995                 name.size = max_valnamelen + 2;
1996                 name.length = 0;
1997
1998                 data = NULL;
1999                 if (size) {
2000                         data = (uint8_t *) talloc_array(tctx, uint8_t *, size);
2001                 }
2002                 r.in.value = data;
2003
2004                 torture_assert_ntstatus_ok(tctx,
2005                                            dcerpc_winreg_EnumValue_r(b, tctx, &r),
2006                                            "EnumValue failed");
2007
2008                 if (W_ERROR_IS_OK(r.out.result)) {
2009                         ret &= test_QueryValue(b, tctx, handle,
2010                                                r.out.name->name);
2011                         ret &= test_QueryMultipleValues(b, tctx, handle,
2012                                                         r.out.name->name);
2013                         ret &= test_QueryMultipleValues2(b, tctx, handle,
2014                                                          r.out.name->name);
2015                 }
2016
2017                 talloc_free(data);
2018
2019                 r.in.enum_index++;
2020         } while (W_ERROR_IS_OK(r.out.result));
2021
2022         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2023                                   "EnumValue failed");
2024
2025         return ret;
2026 }
2027
2028 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2029                                      struct torture_context *tctx)
2030 {
2031         struct winreg_AbortSystemShutdown r;
2032         uint16_t server = 0x0;
2033
2034         ZERO_STRUCT(r);
2035         r.in.server = &server;
2036
2037         torture_assert_ntstatus_ok(tctx,
2038                                    dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2039                                    "AbortSystemShutdown failed");
2040
2041         torture_assert_werr_ok(tctx, r.out.result,
2042                                "AbortSystemShutdown failed");
2043
2044         return true;
2045 }
2046
2047 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2048                                         struct dcerpc_pipe *p)
2049 {
2050         struct winreg_InitiateSystemShutdown r;
2051         uint16_t hostname = 0x0;
2052         struct dcerpc_binding_handle *b = p->binding_handle;
2053
2054         ZERO_STRUCT(r);
2055         r.in.hostname = &hostname;
2056         r.in.message = talloc(tctx, struct lsa_StringLarge);
2057         init_lsa_StringLarge(r.in.message, "spottyfood");
2058         r.in.force_apps = 1;
2059         r.in.timeout = 30;
2060         r.in.do_reboot = 1;
2061
2062         torture_assert_ntstatus_ok(tctx,
2063                                    dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2064                                    "InitiateSystemShutdown failed");
2065
2066         torture_assert_werr_ok(tctx, r.out.result,
2067                                "InitiateSystemShutdown failed");
2068
2069         return test_AbortSystemShutdown(b, tctx);
2070 }
2071
2072
2073 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2074                                           struct dcerpc_pipe *p)
2075 {
2076         struct winreg_InitiateSystemShutdownEx r;
2077         uint16_t hostname = 0x0;
2078         struct dcerpc_binding_handle *b = p->binding_handle;
2079
2080         ZERO_STRUCT(r);
2081         r.in.hostname = &hostname;
2082         r.in.message = talloc(tctx, struct lsa_StringLarge);
2083         init_lsa_StringLarge(r.in.message, "spottyfood");
2084         r.in.force_apps = 1;
2085         r.in.timeout = 30;
2086         r.in.do_reboot = 1;
2087         r.in.reason = 0;
2088
2089         torture_assert_ntstatus_ok(tctx,
2090                 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2091                 "InitiateSystemShutdownEx failed");
2092
2093         torture_assert_werr_ok(tctx, r.out.result,
2094                                "InitiateSystemShutdownEx failed");
2095
2096         return test_AbortSystemShutdown(b, tctx);
2097 }
2098 #define MAX_DEPTH 2             /* Only go this far down the tree */
2099
2100 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2101                      struct policy_handle *handle, int depth,
2102                      bool test_security)
2103 {
2104         struct dcerpc_binding_handle *b = p->binding_handle;
2105         uint32_t max_valnamelen = 0;
2106         uint32_t max_valbufsize = 0;
2107
2108         if (depth == MAX_DEPTH)
2109                 return true;
2110
2111         if (!test_QueryInfoKey(b, tctx, handle, NULL,
2112                                &max_valnamelen, &max_valbufsize)) {
2113         }
2114
2115         if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2116         }
2117
2118         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2119         }
2120
2121         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2122         }
2123
2124         if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2125         }
2126
2127         if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2128         }
2129
2130         test_CloseKey(b, tctx, handle);
2131
2132         return true;
2133 }
2134
2135 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2136                                  struct torture_context *tctx,
2137                                  struct policy_handle *handle)
2138 {
2139         const char *value_name = TEST_VALUE;
2140         uint32_t value = 0x12345678;
2141         uint64_t value2 = 0x12345678;
2142         const char *string = "torture";
2143         const char *array[2];
2144         DATA_BLOB blob;
2145         enum winreg_Type types[] = {
2146                 REG_DWORD,
2147                 REG_DWORD_BIG_ENDIAN,
2148                 REG_QWORD,
2149                 REG_BINARY,
2150                 REG_SZ,
2151                 REG_MULTI_SZ
2152         };
2153         int t;
2154
2155         array[0] = "array0";
2156         array[1] = NULL;
2157
2158         torture_comment(tctx, "Testing SetValue (standard formats)\n");
2159
2160         for (t=0; t < ARRAY_SIZE(types); t++) {
2161
2162                 enum winreg_Type w_type;
2163                 uint32_t w_size, w_length;
2164                 uint8_t *w_data;
2165
2166                 switch (types[t]) {
2167                 case REG_DWORD:
2168                 case REG_DWORD_BIG_ENDIAN:
2169                         blob = data_blob_talloc_zero(tctx, 4);
2170                         SIVAL(blob.data, 0, value);
2171                         break;
2172                 case REG_QWORD:
2173                         blob = data_blob_talloc_zero(tctx, 8);
2174                         SBVAL(blob.data, 0, value2);
2175                         break;
2176                 case REG_BINARY:
2177                         blob = data_blob_string_const("binary_blob");
2178                         break;
2179                 case REG_SZ:
2180                         torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2181                         break;
2182                 case REG_MULTI_SZ:
2183                         torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2184                         break;
2185                 default:
2186                         break;
2187                 }
2188
2189                 torture_assert(tctx,
2190                         test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2191                         "test_SetValue failed");
2192                 torture_assert(tctx,
2193                         test_QueryValue_full(b, tctx, handle, value_name, true),
2194                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2195                 torture_assert(tctx,
2196                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2197                         "test_winreg_QueryValue failed");
2198                 torture_assert(tctx,
2199                         test_DeleteValue(b, tctx, handle, value_name),
2200                         "test_DeleteValue failed");
2201
2202                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2203                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2204                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2205                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2206         }
2207
2208         torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2209
2210         return true;
2211 }
2212
2213 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2214                                  struct torture_context *tctx,
2215                                  struct policy_handle *handle)
2216 {
2217         DATA_BLOB blob;
2218         const char *values[] = {
2219                 "torture_value",
2220                 "torture value",
2221                 "torture,value",
2222                 "torture;value",
2223                 "torture/value",
2224                 "torture\\value",
2225                 "torture_value_name",
2226                 "torture value name",
2227                 "torture,value,name",
2228                 "torture;value;name",
2229                 "torture/value/name",
2230                 "torture\\value\\name",
2231         };
2232         int i;
2233
2234         torture_comment(tctx, "Testing SetValue (values)\n");
2235
2236         for (i=0; i < ARRAY_SIZE(values); i++) {
2237
2238                 enum winreg_Type w_type;
2239                 uint32_t w_size, w_length;
2240                 uint8_t *w_data;
2241
2242                 blob = data_blob_talloc(tctx, NULL, 32);
2243
2244                 generate_random_buffer(blob.data, 32);
2245
2246                 torture_assert(tctx,
2247                         test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2248                         "test_SetValue failed");
2249                 torture_assert(tctx,
2250                         test_QueryValue_full(b, tctx, handle, values[i], true),
2251                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2252                 torture_assert(tctx,
2253                         test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2254                         "test_winreg_QueryValue failed");
2255                 torture_assert(tctx,
2256                         test_DeleteValue(b, tctx, handle, values[i]),
2257                         "test_DeleteValue failed");
2258
2259                 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2260                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2261                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2262                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2263         }
2264
2265         torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2266
2267         return true;
2268 }
2269
2270 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2271
2272 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2273                                    struct torture_context *tctx,
2274                                    struct policy_handle *handle)
2275 {
2276         const char *value_name = TEST_VALUE;
2277         enum winreg_Type types[] = {
2278                 REG_NONE,
2279                 REG_SZ,
2280                 REG_EXPAND_SZ,
2281                 REG_BINARY,
2282                 REG_DWORD,
2283                 REG_DWORD_BIG_ENDIAN,
2284                 REG_LINK,
2285                 REG_MULTI_SZ,
2286                 REG_RESOURCE_LIST,
2287                 REG_FULL_RESOURCE_DESCRIPTOR,
2288                 REG_RESOURCE_REQUIREMENTS_LIST,
2289                 REG_QWORD,
2290                 12,
2291                 13,
2292                 14,
2293                 55,
2294                 123456,
2295                 653210,
2296                 __LINE__
2297         };
2298         int t, l;
2299
2300         if (torture_setting_bool(tctx, "samba4", false)) {
2301                 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2302         }
2303
2304         torture_comment(tctx, "Testing SetValue (extended formats)\n");
2305
2306         for (t=0; t < ARRAY_SIZE(types); t++) {
2307         for (l=0; l < 16; l++) {
2308
2309                 enum winreg_Type w_type;
2310                 uint32_t w_size, w_length;
2311                 uint8_t *w_data;
2312
2313                 uint32_t size;
2314                 uint8_t *data;
2315
2316                 size = l;
2317                 data = talloc_array(tctx, uint8_t, size);
2318
2319                 generate_random_buffer(data, size);
2320
2321                 torture_assert(tctx,
2322                         test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2323                         "test_SetValue failed");
2324
2325                 torture_assert(tctx,
2326                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2327                         "test_winreg_QueryValue failed");
2328
2329                 torture_assert(tctx,
2330                         test_DeleteValue(b, tctx, handle, value_name),
2331                         "test_DeleteValue failed");
2332
2333                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2334                 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2335                 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2336                 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2337         }
2338         }
2339
2340         torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2341
2342         return true;
2343 }
2344
2345 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2346                                  struct torture_context *tctx,
2347                                  struct policy_handle *handle)
2348 {
2349         const char *keys[] = {
2350                 "torture_key",
2351                 "torture key",
2352                 "torture,key",
2353                 "torture/key",
2354                 "torture\\key",
2355         };
2356         int i;
2357
2358         for (i=0; i < ARRAY_SIZE(keys); i++) {
2359
2360                 enum winreg_CreateAction action_taken;
2361                 struct policy_handle new_handle;
2362                 char *q, *tmp;
2363
2364                 torture_assert(tctx,
2365                         test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2366                                             REG_OPTION_NON_VOLATILE,
2367                                             SEC_FLAG_MAXIMUM_ALLOWED,
2368                                             NULL,
2369                                             WERR_OK,
2370                                             &action_taken,
2371                                             &new_handle),
2372                         talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2373
2374                 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2375
2376                 torture_assert(tctx,
2377                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2378                         "failed to delete key");
2379
2380                 torture_assert(tctx,
2381                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2382                         "failed 2nd delete key");
2383
2384                 tmp = talloc_strdup(tctx, keys[i]);
2385
2386                 q = strchr(tmp, '\\');
2387                 if (q != NULL) {
2388                         *q = '\0';
2389                         q++;
2390
2391                         torture_assert(tctx,
2392                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2393                                 "failed to delete key");
2394
2395                         torture_assert(tctx,
2396                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2397                                 "failed 2nd delete key");
2398                 }
2399         }
2400
2401         return true;
2402 }
2403
2404 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2405 #define VALUE_CURRENT_VERSION "CurrentVersion"
2406 #define VALUE_SYSTEM_ROOT "SystemRoot"
2407
2408 static bool test_HKLM_wellknown(struct torture_context *tctx,
2409                                 struct dcerpc_binding_handle *b,
2410                                 struct policy_handle *handle)
2411 {
2412         struct policy_handle newhandle;
2413         int i;
2414         static const struct {
2415                 const char *values[3];
2416                 uint32_t num_values;
2417                 bool existing_value;
2418                 const char *error_message;
2419         } multiple_values_tests[] = {
2420                 {
2421                         .values[0] = VALUE_CURRENT_VERSION,
2422                         .values[1] = NULL,
2423                         .values[2] = NULL,
2424                         .num_values = 1,
2425                         .existing_value = true
2426                 },{
2427                         .values[0] = VALUE_SYSTEM_ROOT,
2428                         .values[1] = NULL,
2429                         .values[2] = NULL,
2430                         .num_values = 1,
2431                         .existing_value = true
2432                 },{
2433                         .values[0] = VALUE_CURRENT_VERSION,
2434                         .values[1] = VALUE_SYSTEM_ROOT,
2435                         .values[2] = NULL,
2436                         .num_values = 2,
2437                         .existing_value = true
2438                 },{
2439                         .values[0] = VALUE_CURRENT_VERSION,
2440                         .values[1] = VALUE_SYSTEM_ROOT,
2441                         .values[2] = VALUE_CURRENT_VERSION,
2442                         .num_values = 3,
2443                         .existing_value = true
2444                 },{
2445                         .values[0] = VALUE_CURRENT_VERSION,
2446                         .values[1] = NULL,
2447                         .values[2] = VALUE_SYSTEM_ROOT,
2448                         .num_values = 3,
2449                         .existing_value = false
2450                 },{
2451                         .values[0] = VALUE_CURRENT_VERSION,
2452                         .values[1] = "",
2453                         .values[2] = VALUE_SYSTEM_ROOT,
2454                         .num_values = 3,
2455                         .existing_value = false
2456                 },{
2457                         .values[0] = "IDoNotExist",
2458                         .values[1] = NULL,
2459                         .values[2] = NULL,
2460                         .num_values = 1,
2461                         .existing_value = false
2462                 },{
2463                         .values[0] = "IDoNotExist",
2464                         .values[1] = VALUE_CURRENT_VERSION,
2465                         .values[2] = NULL,
2466                         .num_values = 2,
2467                         .existing_value = false
2468                 },{
2469                         .values[0] = VALUE_CURRENT_VERSION,
2470                         .values[1] = "IDoNotExist",
2471                         .values[2] = NULL,
2472                         .num_values = 2,
2473                         .existing_value = false
2474                 }
2475         };
2476
2477         /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2478         if (torture_setting_bool(tctx, "samba3", false)) {
2479                 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2480                                KEY_CURRENT_VERSION,
2481                                REG_OPTION_NON_VOLATILE,
2482                                KEY_QUERY_VALUE,
2483                                &newhandle,
2484                                WERR_OK),
2485                         "failed to open current version key");
2486         } else {
2487                 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2488                         "failed to open current version key");
2489         }
2490
2491         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2492                 "failed to query current version");
2493         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2494                 "succeeded to query nonexistent value");
2495         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2496                 "succeeded to query value with NULL name");
2497         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2498                 "succeeded to query nonexistent default value (\"\")");
2499
2500         if (torture_setting_bool(tctx, "samba4", false)) {
2501                 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2502                 goto close_key;
2503         }
2504
2505         for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2506                 const char *msg;
2507                 msg = talloc_asprintf(tctx,
2508                                 "failed to query %d %sexisting values\n",
2509                                         multiple_values_tests[i].num_values,
2510                                         multiple_values_tests[i].existing_value ? "":"non");
2511
2512                 torture_assert(tctx,
2513                         test_QueryMultipleValues_full(b, tctx, &newhandle,
2514                                                       multiple_values_tests[i].num_values,
2515                                                       multiple_values_tests[i].values,
2516                                                       multiple_values_tests[i].existing_value),
2517                         msg);
2518                 torture_assert(tctx,
2519                         test_QueryMultipleValues2_full(b, tctx, &newhandle,
2520                                                        multiple_values_tests[i].num_values,
2521                                                        multiple_values_tests[i].values,
2522                                                        multiple_values_tests[i].existing_value),
2523                         msg);
2524         }
2525
2526  close_key:
2527         torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2528                 "failed to close current version key");
2529
2530         return true;
2531 }
2532
2533 static bool test_OpenHive(struct torture_context *tctx,
2534                           struct dcerpc_binding_handle *b,
2535                           struct policy_handle *handle,
2536                           int hkey)
2537 {
2538         struct winreg_OpenHKLM r;
2539
2540         r.in.system_name = 0;
2541         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2542         r.out.handle = handle;
2543
2544         switch (hkey) {
2545         case HKEY_LOCAL_MACHINE:
2546                 torture_assert_ntstatus_ok(tctx,
2547                         dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2548                         "failed to open HKLM");
2549                 torture_assert_werr_ok(tctx, r.out.result,
2550                         "failed to open HKLM");
2551                 break;
2552         case HKEY_CURRENT_USER:
2553                 torture_assert_ntstatus_ok(tctx,
2554                         dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2555                         "failed to open HKCU");
2556                 torture_assert_werr_ok(tctx, r.out.result,
2557                         "failed to open HKCU");
2558                 break;
2559         case HKEY_USERS:
2560                 torture_assert_ntstatus_ok(tctx,
2561                         dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2562                         "failed to open HKU");
2563                 torture_assert_werr_ok(tctx, r.out.result,
2564                         "failed to open HKU");
2565                 break;
2566         case HKEY_CLASSES_ROOT:
2567                 torture_assert_ntstatus_ok(tctx,
2568                         dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2569                         "failed to open HKCR");
2570                 torture_assert_werr_ok(tctx, r.out.result,
2571                         "failed to open HKCR");
2572                 break;
2573         default:
2574                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2575                 return false;
2576         }
2577
2578         return true;
2579 }
2580
2581 static bool test_volatile_keys(struct torture_context *tctx,
2582                                struct dcerpc_binding_handle *b,
2583                                struct policy_handle *handle,
2584                                int hkey)
2585 {
2586         struct policy_handle new_handle, hive_handle;
2587         enum winreg_CreateAction action_taken;
2588
2589         torture_comment(tctx, "Testing VOLATILE key\n");
2590
2591         test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2592
2593         torture_assert(tctx,
2594                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2595                                     REG_OPTION_VOLATILE,
2596                                     SEC_FLAG_MAXIMUM_ALLOWED,
2597                                     NULL,
2598                                     WERR_OK,
2599                                     &action_taken,
2600                                     &new_handle),
2601                 "failed to create REG_OPTION_VOLATILE type key");
2602
2603         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2604
2605         torture_assert(tctx,
2606                 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2607                                     REG_OPTION_NON_VOLATILE,
2608                                     SEC_FLAG_MAXIMUM_ALLOWED,
2609                                     NULL,
2610                                     WERR_CHILD_MUST_BE_VOLATILE,
2611                                     NULL,
2612                                     NULL),
2613                 "failed to fail create REG_OPTION_VOLATILE type key");
2614
2615         torture_assert(tctx,
2616                 test_CloseKey(b, tctx, &new_handle),
2617                 "failed to close");
2618
2619         torture_assert(tctx,
2620                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2621                                   REG_OPTION_NON_VOLATILE,
2622                                   SEC_FLAG_MAXIMUM_ALLOWED,
2623                                   &new_handle,
2624                                   WERR_OK),
2625                 "failed to open volatile key");
2626
2627         torture_assert(tctx,
2628                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2629                 "failed to delete key");
2630
2631         torture_assert(tctx,
2632                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2633                                     REG_OPTION_VOLATILE,
2634                                     SEC_FLAG_MAXIMUM_ALLOWED,
2635                                     NULL,
2636                                     WERR_OK,
2637                                     &action_taken,
2638                                     &new_handle),
2639                 "failed to create REG_OPTION_VOLATILE type key");
2640
2641         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2642
2643         torture_assert(tctx,
2644                 test_CloseKey(b, tctx, &new_handle),
2645                 "failed to close");
2646
2647         torture_assert(tctx,
2648                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2649                                   REG_OPTION_VOLATILE,
2650                                   SEC_FLAG_MAXIMUM_ALLOWED,
2651                                   &new_handle,
2652                                   WERR_OK),
2653                 "failed to open volatile key");
2654
2655         torture_assert(tctx,
2656                 test_CloseKey(b, tctx, &new_handle),
2657                 "failed to close");
2658
2659         torture_assert(tctx,
2660                 test_OpenHive(tctx, b, &hive_handle, hkey),
2661                 "failed top open hive");
2662
2663         torture_assert(tctx,
2664                 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2665                                   REG_OPTION_VOLATILE,
2666                                   SEC_FLAG_MAXIMUM_ALLOWED,
2667                                   &new_handle,
2668                                   WERR_BADFILE),
2669                 "failed to open volatile key");
2670
2671         torture_assert(tctx,
2672                 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2673                                   REG_OPTION_NON_VOLATILE,
2674                                   SEC_FLAG_MAXIMUM_ALLOWED,
2675                                   &new_handle,
2676                                   WERR_BADFILE),
2677                 "failed to open volatile key");
2678
2679         torture_assert(tctx,
2680                 test_CloseKey(b, tctx, &hive_handle),
2681                 "failed to close");
2682
2683         torture_assert(tctx,
2684                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2685                 "failed to delete key");
2686
2687
2688         torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2689
2690         return true;
2691 }
2692
2693 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2694                                              int hkey,
2695                                              const char *sid_string,
2696                                              const char *path)
2697 {
2698         switch (hkey) {
2699         case HKEY_LOCAL_MACHINE:
2700                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2701         case HKEY_CURRENT_USER:
2702                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2703         case HKEY_USERS:
2704                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2705         case HKEY_CLASSES_ROOT:
2706                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2707         default:
2708                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2709                 return NULL;
2710         }
2711 }
2712
2713 static bool test_symlink_keys(struct torture_context *tctx,
2714                               struct dcerpc_binding_handle *b,
2715                               struct policy_handle *handle,
2716                               const char *key,
2717                               int hkey)
2718 {
2719         struct policy_handle new_handle;
2720         enum winreg_CreateAction action_taken;
2721         DATA_BLOB blob;
2722         uint32_t value = 42;
2723         const char *test_key_symlink_dest;
2724         const char *test_key_symlink;
2725         const char *kernel_mode_path;
2726
2727         /* disable until we know how to delete a symbolic link */
2728         torture_skip(tctx, "symlink test disabled");
2729
2730         torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2731
2732         /* create destination key with testvalue */
2733         test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2734                         key, TEST_KEY_SYMLINK);
2735         test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2736                         key, TEST_KEY_SYMLINK_DEST);
2737
2738         test_DeleteKey(b, tctx, handle, test_key_symlink);
2739
2740         torture_assert(tctx,
2741                 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2742                                     0,
2743                                     SEC_FLAG_MAXIMUM_ALLOWED,
2744                                     NULL,
2745                                     WERR_OK,
2746                                     &action_taken,
2747                                     &new_handle),
2748                 "failed to create symlink destination");
2749
2750         blob = data_blob_talloc_zero(tctx, 4);
2751         SIVAL(blob.data, 0, value);
2752
2753         torture_assert(tctx,
2754                 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2755                 "failed to create TestValue");
2756
2757         torture_assert(tctx,
2758                 test_CloseKey(b, tctx, &new_handle),
2759                 "failed to close");
2760
2761         /* create symlink */
2762
2763         torture_assert(tctx,
2764                 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2765                                     REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2766                                     SEC_FLAG_MAXIMUM_ALLOWED,
2767                                     NULL,
2768                                     WERR_OK,
2769                                     &action_taken,
2770                                     &new_handle),
2771                 "failed to create REG_OPTION_CREATE_LINK type key");
2772
2773         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2774
2775         kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2776
2777         torture_assert(tctx,
2778                 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2779                                       kernel_mode_path,
2780                                       strlen(kernel_mode_path), /* not NULL terminated */
2781                                       &blob.data, &blob.length,
2782                                       false),
2783                 "failed to convert");
2784
2785         torture_assert(tctx,
2786                 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2787                 "failed to create SymbolicLinkValue value");
2788
2789         torture_assert(tctx,
2790                 test_CloseKey(b, tctx, &new_handle),
2791                 "failed to close");
2792
2793         /* test follow symlink */
2794
2795         torture_assert(tctx,
2796                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2797                                   0,
2798                                   SEC_FLAG_MAXIMUM_ALLOWED,
2799                                   &new_handle,
2800                                   WERR_OK),
2801                 "failed to follow symlink key");
2802
2803         torture_assert(tctx,
2804                 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2805                 "failed to query value");
2806
2807         torture_assert(tctx,
2808                 test_CloseKey(b, tctx, &new_handle),
2809                 "failed to close");
2810
2811         /* delete link */
2812
2813         torture_assert(tctx,
2814                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2815                                   REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2816                                   SEC_FLAG_MAXIMUM_ALLOWED,
2817                                   &new_handle,
2818                                   WERR_OK),
2819                 "failed to open symlink key");
2820
2821         torture_assert(tctx,
2822                 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2823                 "failed to delete value SymbolicLinkValue");
2824
2825         torture_assert(tctx,
2826                 test_CloseKey(b, tctx, &new_handle),
2827                 "failed to close");
2828
2829         torture_assert(tctx,
2830                 test_DeleteKey(b, tctx, handle, test_key_symlink),
2831                 "failed to delete key");
2832
2833         /* delete destination */
2834
2835         torture_assert(tctx,
2836                 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2837                 "failed to delete key");
2838
2839         return true;
2840 }
2841
2842 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2843                                     struct dcerpc_binding_handle *b,
2844                                     struct policy_handle *handle,
2845                                     const char *key,
2846                                     int hkey)
2847 {
2848
2849         if (torture_setting_bool(tctx, "samba3", false) ||
2850             torture_setting_bool(tctx, "samba4", false)) {
2851                 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2852         }
2853
2854         torture_assert(tctx,
2855                 test_volatile_keys(tctx, b, handle, hkey),
2856                 "failed to test volatile keys");
2857
2858         torture_assert(tctx,
2859                 test_symlink_keys(tctx, b, handle, key, hkey),
2860                 "failed to test symlink keys");
2861
2862         return true;
2863 }
2864
2865 static bool test_key_base(struct torture_context *tctx,
2866                           struct dcerpc_binding_handle *b,
2867                           struct policy_handle *handle,
2868                           const char *base_key,
2869                           int hkey)
2870 {
2871         struct policy_handle newhandle;
2872         bool ret = true, created = false, deleted = false;
2873         bool created3 = false;
2874         const char *test_key1;
2875         const char *test_key3;
2876         const char *test_subkey;
2877
2878         test_Cleanup(b, tctx, handle, base_key);
2879
2880         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2881                 torture_comment(tctx,
2882                                 "CreateKey(%s) failed\n", base_key);
2883         }
2884
2885         test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2886
2887         if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2888                 torture_comment(tctx,
2889                                 "CreateKey failed - not considering a failure\n");
2890         } else {
2891                 created = true;
2892         }
2893
2894         if (created) {
2895                 if (!test_FlushKey(b, tctx, handle)) {
2896                         torture_comment(tctx, "FlushKey failed\n");
2897                         ret = false;
2898                 }
2899
2900                 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2901                         torture_fail(tctx,
2902                                      "CreateKey failed (OpenKey after Create didn't work)\n");
2903                 }
2904
2905                 if (hkey == HKEY_CURRENT_USER) {
2906                         torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2907                                 "simple SetValue test failed");
2908                         torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2909                                 "values SetValue test failed");
2910                         torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2911                                 "extended SetValue test failed");
2912                         torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2913                                 "keyname CreateKey test failed");
2914                 } else {
2915                         torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2916                                 "keytype test failed");
2917                 }
2918
2919                 if (!test_CloseKey(b, tctx, &newhandle)) {
2920                         torture_fail(tctx,
2921                                      "CreateKey failed (CloseKey after Open didn't work)\n");
2922                 }
2923
2924                 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2925                         torture_comment(tctx, "DeleteKey(%s) failed\n",
2926                                               test_key1);
2927                         ret = false;
2928                 } else {
2929                         deleted = true;
2930                 }
2931
2932                 if (!test_FlushKey(b, tctx, handle)) {
2933                         torture_comment(tctx, "FlushKey failed\n");
2934                         ret = false;
2935                 }
2936
2937                 if (deleted) {
2938                         if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2939                                                REG_OPTION_NON_VOLATILE,
2940                                                SEC_FLAG_MAXIMUM_ALLOWED,
2941                                                &newhandle,
2942                                                WERR_BADFILE)) {
2943                                 torture_comment(tctx,
2944                                                 "DeleteKey failed (OpenKey after Delete "
2945                                                 "did not return WERR_BADFILE)\n");
2946                                 ret = false;
2947                         }
2948                 }
2949
2950                 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2951
2952                 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2953                         created3 = true;
2954                 }
2955
2956                 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2957
2958                 if (created3) {
2959                         if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2960                                 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2961                                         torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
2962                                         ret = false;
2963                                 }
2964                         }
2965
2966                         if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2967                                 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
2968                                 ret = false;
2969                         }
2970                 }
2971         }
2972
2973         test_Cleanup(b, tctx, handle, base_key);
2974
2975         return ret;
2976 }
2977
2978 static bool test_key_base_sd(struct torture_context *tctx,
2979                              struct dcerpc_pipe *p,
2980                              struct policy_handle *handle,
2981                              const char *base_key)
2982 {
2983         struct policy_handle newhandle;
2984         bool ret = true, created2 = false, created4 = false;
2985         struct dcerpc_binding_handle *b = p->binding_handle;
2986         const char *test_key2;
2987         const char *test_key4;
2988
2989         torture_skip(tctx, "security descriptor test disabled\n");
2990
2991         if (torture_setting_bool(tctx, "samba3", false) ||
2992             torture_setting_bool(tctx, "samba4", false)) {
2993                 torture_skip(tctx, "skipping security descriptor tests against Samba");
2994         }
2995
2996         test_Cleanup(b, tctx, handle, base_key);
2997
2998         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2999                 torture_comment(tctx,
3000                                 "CreateKey(%s) failed\n", base_key);
3001         }
3002
3003         test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
3004
3005         if (test_CreateKey_sd(b, tctx, handle, test_key2,
3006                               NULL, &newhandle)) {
3007                 created2 = true;
3008         }
3009
3010         if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3011                 torture_comment(tctx, "CloseKey failed\n");
3012                 ret = false;
3013         }
3014
3015         test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3016
3017         if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3018                 created4 = true;
3019         }
3020
3021         if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3022                 torture_comment(tctx, "CloseKey failed\n");
3023                 ret = false;
3024         }
3025
3026         if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3027                 ret = false;
3028         }
3029
3030         if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3031                 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3032                 ret = false;
3033         }
3034
3035         if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3036                 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3037                 ret = false;
3038         }
3039
3040         test_Cleanup(b, tctx, handle, base_key);
3041
3042         return ret;
3043 }
3044
3045 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3046                       void *userdata)
3047 {
3048         struct policy_handle handle;
3049         bool ret = true;
3050         struct winreg_OpenHKLM r;
3051         struct dcerpc_binding_handle *b = p->binding_handle;
3052         const char *torture_base_key;
3053         int hkey = 0;
3054
3055         winreg_open_fn open_fn = (winreg_open_fn)userdata;
3056
3057         r.in.system_name = 0;
3058         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3059         r.out.handle = &handle;
3060
3061         torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3062                                    "open");
3063
3064         if (!test_GetVersion(b, tctx, &handle)) {
3065                 torture_comment(tctx, "GetVersion failed\n");
3066                 ret = false;
3067         }
3068
3069         if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3070                 hkey = HKEY_LOCAL_MACHINE;
3071                 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3072         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3073                 hkey = HKEY_USERS;
3074                 torture_base_key = TEST_KEY_BASE;
3075         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3076                 hkey = HKEY_CLASSES_ROOT;
3077                 torture_base_key = TEST_KEY_BASE;
3078         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3079                 hkey = HKEY_CURRENT_USER;
3080                 torture_base_key = TEST_KEY_BASE;
3081         } else {
3082                 torture_fail(tctx, "unsupported hkey");
3083         }
3084
3085         if (hkey == HKEY_LOCAL_MACHINE) {
3086                 torture_assert(tctx,
3087                         test_HKLM_wellknown(tctx, b, &handle),
3088                         "failed to test HKLM wellknown keys");
3089         }
3090
3091         if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3092                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3093                                 torture_base_key);
3094                 ret = false;
3095         }
3096
3097         if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3098                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3099                                 torture_base_key);
3100                 ret = false;
3101         }
3102
3103         /* The HKCR hive has a very large fanout */
3104         if (hkey == HKEY_CLASSES_ROOT) {
3105                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3106                         ret = false;
3107                 }
3108         } else if (hkey == HKEY_LOCAL_MACHINE) {
3109                 /* FIXME we are not allowed to enum values in the HKLM root */
3110         } else {
3111                 if (!test_key(p, tctx, &handle, 0, false)) {
3112                         ret = false;
3113                 }
3114         }
3115
3116         return ret;
3117 }
3118
3119 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3120 {
3121         struct torture_rpc_tcase *tcase;
3122         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
3123         struct torture_test *test;
3124
3125         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3126                                                   &ndr_table_winreg);
3127
3128         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3129                                           test_InitiateSystemShutdown);
3130         test->dangerous = true;
3131
3132         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3133                                           test_InitiateSystemShutdownEx);
3134         test->dangerous = true;
3135
3136         torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3137                                       test_Open,
3138                                       (void *)dcerpc_winreg_OpenHKLM_r);
3139         torture_rpc_tcase_add_test_ex(tcase, "HKU",
3140                                       test_Open,
3141                                       (void *)dcerpc_winreg_OpenHKU_r);
3142         torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3143                                       test_Open,
3144                                       (void *)dcerpc_winreg_OpenHKCR_r);
3145         torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3146                                       test_Open,
3147                                       (void *)dcerpc_winreg_OpenHKCU_r);
3148
3149         return suite;
3150 }