s4-smbtorture: enable extended SetValue test against Samba3.
[metze/samba/wip.git] / source4 / torture / rpc / winreg.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for winreg rpc operations
4
5    Copyright (C) Tim Potter 2003
6    Copyright (C) Jelmer Vernooij 2004-2007
7    Copyright (C) Günther Deschner 2007,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, char *kclass)
1465 {
1466         struct winreg_QueryInfoKey r;
1467         uint32_t num_subkeys, max_subkeylen, max_classlen,
1468                 num_values, max_valnamelen, max_valbufsize,
1469                 secdescsize;
1470         NTTIME last_changed_time;
1471
1472         ZERO_STRUCT(r);
1473         r.in.handle = handle;
1474         r.out.num_subkeys = &num_subkeys;
1475         r.out.max_subkeylen = &max_subkeylen;
1476         r.out.max_classlen = &max_classlen;
1477         r.out.num_values = &num_values;
1478         r.out.max_valnamelen = &max_valnamelen;
1479         r.out.max_valbufsize = &max_valbufsize;
1480         r.out.secdescsize = &secdescsize;
1481         r.out.last_changed_time = &last_changed_time;
1482
1483         r.out.classname = talloc(tctx, struct winreg_String);
1484
1485         r.in.classname = talloc(tctx, struct winreg_String);
1486         init_winreg_String(r.in.classname, kclass);
1487
1488         torture_assert_ntstatus_ok(tctx,
1489                                    dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1490                                    "QueryInfoKey failed");
1491
1492         torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1493
1494         return true;
1495 }
1496
1497 static bool test_SetValue(struct dcerpc_binding_handle *b,
1498                           struct torture_context *tctx,
1499                           struct policy_handle *handle,
1500                           const char *value_name,
1501                           enum winreg_Type type,
1502                           uint8_t *data,
1503                           uint32_t size)
1504 {
1505         struct winreg_SetValue r;
1506         struct winreg_String name;
1507
1508         torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1509                 value_name, str_regtype(type), size);
1510
1511         init_winreg_String(&name, value_name);
1512
1513         r.in.handle = handle;
1514         r.in.name = name;
1515         r.in.type = type;
1516         r.in.data = data;
1517         r.in.size = size;
1518
1519         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1520                 "winreg_SetValue failed");
1521         torture_assert_werr_ok(tctx, r.out.result,
1522                 "winreg_SetValue failed");
1523
1524         return true;
1525 }
1526
1527 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1528                              struct torture_context *tctx,
1529                              struct policy_handle *handle,
1530                              const char *value_name)
1531 {
1532         struct winreg_DeleteValue r;
1533         struct winreg_String value;
1534
1535         torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1536
1537         init_winreg_String(&value, value_name);
1538
1539         r.in.handle = handle;
1540         r.in.value = value;
1541
1542         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1543                 "winreg_DeleteValue failed");
1544         torture_assert_werr_ok(tctx, r.out.result,
1545                 "winreg_DeleteValue failed");
1546
1547         return true;
1548 }
1549
1550 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1551                      struct policy_handle *handle, int depth,
1552                      bool test_security);
1553
1554 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1555                          struct policy_handle *handle, int depth,
1556                          bool test_security)
1557 {
1558         struct winreg_EnumKey r;
1559         struct winreg_StringBuf kclass, name;
1560         NTSTATUS status;
1561         NTTIME t = 0;
1562         struct dcerpc_binding_handle *b = p->binding_handle;
1563
1564         kclass.name   = "";
1565         kclass.size   = 1024;
1566
1567         ZERO_STRUCT(r);
1568         r.in.handle = handle;
1569         r.in.enum_index = 0;
1570         r.in.name = &name;
1571         r.in.keyclass = &kclass;
1572         r.out.name = &name;
1573         r.in.last_changed_time = &t;
1574
1575         do {
1576                 name.name   = NULL;
1577                 name.size   = 1024;
1578
1579                 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1580
1581                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1582                         struct policy_handle key_handle;
1583
1584                         torture_comment(tctx, "EnumKey: %d: %s\n",
1585                                         r.in.enum_index,
1586                                         r.out.name->name);
1587
1588                         if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1589                                           &key_handle)) {
1590                         } else {
1591                                 test_key(p, tctx, &key_handle,
1592                                          depth + 1, test_security);
1593                         }
1594                 }
1595
1596                 r.in.enum_index++;
1597
1598         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1599
1600         torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1601
1602         if (!W_ERROR_IS_OK(r.out.result) &&
1603                 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1604                 torture_fail(tctx, "EnumKey failed");
1605         }
1606
1607         return true;
1608 }
1609
1610 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1611                                      struct torture_context *tctx,
1612                                      struct policy_handle *handle,
1613                                      const char *valuename)
1614 {
1615         struct winreg_QueryMultipleValues r;
1616         uint32_t bufsize=0;
1617
1618         ZERO_STRUCT(r);
1619
1620         r.in.key_handle = handle;
1621         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1622         r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1623         r.in.values_in[0].ve_valuename->name = valuename;
1624         /* size needs to be set manually for winreg_ValNameBuf */
1625         r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1626
1627         r.in.num_values = 1;
1628         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1629         *r.in.buffer_size = bufsize;
1630         do {
1631                 *r.in.buffer_size = bufsize;
1632                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1633                                                                *r.in.buffer_size);
1634
1635                 torture_assert_ntstatus_ok(tctx,
1636                         dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1637                         "QueryMultipleValues failed");
1638
1639                 talloc_free(r.in.buffer);
1640                 bufsize += 0x20;
1641         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1642
1643         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1644
1645         return true;
1646 }
1647
1648 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1649                                           struct torture_context *tctx,
1650                                           struct policy_handle *handle,
1651                                           uint32_t num_values,
1652                                           const char **valuenames,
1653                                           bool existing_value)
1654 {
1655         struct winreg_QueryMultipleValues r;
1656         uint32_t bufsize = 0;
1657         int i;
1658
1659         torture_comment(tctx, "Testing QueryMultipleValues\n");
1660
1661         ZERO_STRUCT(r);
1662
1663         r.in.key_handle = handle;
1664         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1665         r.in.buffer_size = r.out.buffer_size = &bufsize;
1666
1667         torture_assert_ntstatus_ok(tctx,
1668                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1669                 "QueryMultipleValues failed");
1670         torture_assert_werr_ok(tctx, r.out.result,
1671                 "QueryMultipleValues failed");
1672
1673         /* this test crashes w2k8 remote registry */
1674 #if 0
1675         r.in.num_values = num_values;
1676         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
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 #endif
1684         r.in.num_values = num_values;
1685         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1686         for (i=0; i < r.in.num_values; i++) {
1687                 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1688                 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1689                 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1690         }
1691
1692         torture_assert_ntstatus_ok(tctx,
1693                 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1694                 "QueryMultipleValues failed");
1695         torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1696                 "QueryMultipleValues failed");
1697
1698         if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1699                 return true;
1700         }
1701
1702         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1703                 *r.in.buffer_size = 0xff;
1704                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1705
1706                 torture_assert_ntstatus_ok(tctx,
1707                         dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1708                         "QueryMultipleValues failed");
1709         }
1710
1711         torture_assert_werr_ok(tctx, r.out.result,
1712                 "QueryMultipleValues failed");
1713
1714         return true;
1715 }
1716
1717
1718 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1719                                            struct torture_context *tctx,
1720                                            struct policy_handle *handle,
1721                                            uint32_t num_values,
1722                                            const char **valuenames,
1723                                            bool existing_value)
1724 {
1725         struct winreg_QueryMultipleValues2 r;
1726         uint32_t offered = 0, needed;
1727         int i;
1728
1729         torture_comment(tctx, "Testing QueryMultipleValues2\n");
1730
1731         ZERO_STRUCT(r);
1732
1733         r.in.key_handle = handle;
1734         r.in.offered = &offered;
1735         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1736         r.out.needed = &needed;
1737
1738         torture_assert_ntstatus_ok(tctx,
1739                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1740                 "QueryMultipleValues2 failed");
1741         torture_assert_werr_ok(tctx, r.out.result,
1742                 "QueryMultipleValues2 failed");
1743
1744         /* this test crashes w2k8 remote registry */
1745 #if 0
1746         r.in.num_values = num_values;
1747         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
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 #endif
1755         r.in.num_values = num_values;
1756         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1757         for (i=0; i < r.in.num_values; i++) {
1758                 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1759                 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1760                 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1761         }
1762
1763         torture_assert_ntstatus_ok(tctx,
1764                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1765                 "QueryMultipleValues2 failed");
1766         torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1767                 "QueryMultipleValues2 failed");
1768
1769         if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1770                 return true;
1771         }
1772
1773         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1774                 *r.in.offered = *r.out.needed;
1775                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1776
1777                 torture_assert_ntstatus_ok(tctx,
1778                         dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1779                         "QueryMultipleValues2 failed");
1780         }
1781
1782         torture_assert_werr_ok(tctx, r.out.result,
1783                 "QueryMultipleValues2 failed");
1784
1785         return true;
1786 }
1787
1788 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1789                                       struct torture_context *tctx,
1790                                       struct policy_handle *handle,
1791                                       const char *valuename)
1792 {
1793         struct winreg_QueryMultipleValues2 r;
1794         uint32_t offered = 0, needed;
1795
1796         ZERO_STRUCT(r);
1797
1798         r.in.key_handle = handle;
1799         r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1800         r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1801         r.in.values_in[0].ve_valuename->name = valuename;
1802         /* size needs to be set manually for winreg_ValNameBuf */
1803         r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1804
1805         r.in.num_values = 1;
1806         r.in.offered = &offered;
1807         r.out.needed = &needed;
1808
1809         torture_assert_ntstatus_ok(tctx,
1810                 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1811                 "QueryMultipleValues2 failed");
1812         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1813                 *r.in.offered = *r.out.needed;
1814                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1815
1816                 torture_assert_ntstatus_ok(tctx,
1817                         dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1818                         "QueryMultipleValues2 failed");
1819         }
1820
1821         torture_assert_werr_ok(tctx, r.out.result,
1822                 "QueryMultipleValues2 failed");
1823
1824         return true;
1825 }
1826
1827 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1828                             struct torture_context *tctx,
1829                             struct policy_handle *handle,
1830                             const char *valuename)
1831 {
1832         struct winreg_QueryValue r;
1833         NTSTATUS status;
1834         enum winreg_Type zero_type = 0;
1835         uint32_t offered = 0xfff;
1836         uint32_t zero = 0;
1837
1838         ZERO_STRUCT(r);
1839         r.in.handle = handle;
1840         r.in.data = NULL;
1841         r.in.value_name = talloc_zero(tctx, struct winreg_String);
1842         r.in.value_name->name = valuename;
1843         r.in.type = &zero_type;
1844         r.in.data_size = &offered;
1845         r.in.data_length = &zero;
1846
1847         status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1848         if (NT_STATUS_IS_ERR(status)) {
1849                 torture_fail(tctx, "QueryValue failed");
1850         }
1851
1852         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1853
1854         return true;
1855 }
1856
1857 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1858                                  struct torture_context *tctx,
1859                                  struct policy_handle *handle,
1860                                  const char *valuename,
1861                                  bool existing_value)
1862 {
1863         struct winreg_QueryValue r;
1864         struct winreg_String value_name;
1865         enum winreg_Type type = REG_NONE;
1866         uint32_t data_size = 0;
1867         uint32_t real_data_size = 0;
1868         uint32_t data_length = 0;
1869         uint8_t *data = NULL;
1870         WERROR expected_error = WERR_BADFILE;
1871         const char *errmsg_nonexisting = "expected WERR_BADFILE for nonexisting value";
1872
1873         if (valuename == NULL) {
1874                 expected_error = WERR_INVALID_PARAM;
1875                 errmsg_nonexisting = "expected WERR_INVALID_PARAM for NULL valuename";
1876         }
1877
1878         ZERO_STRUCT(r);
1879
1880         init_winreg_String(&value_name, NULL);
1881
1882         torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1883
1884         r.in.handle = handle;
1885         r.in.value_name = &value_name;
1886
1887         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1888         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1889                 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1890
1891         init_winreg_String(&value_name, valuename);
1892         r.in.value_name = &value_name;
1893
1894         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1895                 "QueryValue failed");
1896         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1897                 "expected WERR_INVALID_PARAM for missing type length and size");
1898
1899         r.in.type = &type;
1900         r.out.type = &type;
1901         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1902                 "QueryValue failed");
1903         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1904                 "expected WERR_INVALID_PARAM for missing length and size");
1905
1906         r.in.data_length = &data_length;
1907         r.out.data_length = &data_length;
1908         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1909                 "QueryValue failed");
1910         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1911                 "expected WERR_INVALID_PARAM for missing size");
1912
1913         r.in.data_size = &data_size;
1914         r.out.data_size = &data_size;
1915         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1916                 "QueryValue failed");
1917         if (existing_value) {
1918                 torture_assert_werr_ok(tctx, r.out.result,
1919                         "QueryValue failed");
1920         } else {
1921                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1922                         errmsg_nonexisting);
1923         }
1924
1925         real_data_size = *r.out.data_size;
1926
1927         data = talloc_zero_array(tctx, uint8_t, 0);
1928         r.in.data = data;
1929         r.out.data = data;
1930         *r.in.data_size = 0;
1931         *r.out.data_size = 0;
1932         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1933                 "QueryValue failed");
1934         if (existing_value) {
1935                 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1936                         "expected WERR_MORE_DATA for query with too small buffer");
1937         } else {
1938                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1939                         errmsg_nonexisting);
1940         }
1941
1942         data = talloc_zero_array(tctx, uint8_t, real_data_size);
1943         r.in.data = data;
1944         r.out.data = data;
1945         r.in.data_size = &real_data_size;
1946         r.out.data_size = &real_data_size;
1947         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1948                 "QueryValue failed");
1949         if (existing_value) {
1950                 torture_assert_werr_ok(tctx, r.out.result,
1951                         "QueryValue failed");
1952         } else {
1953                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1954                         errmsg_nonexisting);
1955         }
1956
1957         return true;
1958 }
1959
1960 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1961                            struct torture_context *tctx,
1962                            struct policy_handle *handle, int max_valnamelen,
1963                            int max_valbufsize)
1964 {
1965         struct winreg_EnumValue r;
1966         enum winreg_Type type = 0;
1967         uint32_t size = max_valbufsize, zero = 0;
1968         bool ret = true;
1969         uint8_t buf8;
1970         struct winreg_ValNameBuf name;
1971
1972         name.name   = "";
1973         name.size   = 1024;
1974
1975         ZERO_STRUCT(r);
1976         r.in.handle = handle;
1977         r.in.enum_index = 0;
1978         r.in.name = &name;
1979         r.out.name = &name;
1980         r.in.type = &type;
1981         r.in.value = &buf8;
1982         r.in.length = &zero;
1983         r.in.size = &size;
1984
1985         do {
1986                 torture_assert_ntstatus_ok(tctx,
1987                                            dcerpc_winreg_EnumValue_r(b, tctx, &r),
1988                                            "EnumValue failed");
1989
1990                 if (W_ERROR_IS_OK(r.out.result)) {
1991                         ret &= test_QueryValue(b, tctx, handle,
1992                                                r.out.name->name);
1993                         ret &= test_QueryMultipleValues(b, tctx, handle,
1994                                                         r.out.name->name);
1995                         ret &= test_QueryMultipleValues2(b, tctx, handle,
1996                                                          r.out.name->name);
1997                 }
1998
1999                 r.in.enum_index++;
2000         } while (W_ERROR_IS_OK(r.out.result));
2001
2002         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2003                                   "EnumValue failed");
2004
2005         return ret;
2006 }
2007
2008 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2009                                      struct torture_context *tctx)
2010 {
2011         struct winreg_AbortSystemShutdown r;
2012         uint16_t server = 0x0;
2013
2014         ZERO_STRUCT(r);
2015         r.in.server = &server;
2016
2017         torture_assert_ntstatus_ok(tctx,
2018                                    dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2019                                    "AbortSystemShutdown failed");
2020
2021         torture_assert_werr_ok(tctx, r.out.result,
2022                                "AbortSystemShutdown failed");
2023
2024         return true;
2025 }
2026
2027 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2028                                         struct dcerpc_pipe *p)
2029 {
2030         struct winreg_InitiateSystemShutdown r;
2031         uint16_t hostname = 0x0;
2032         struct dcerpc_binding_handle *b = p->binding_handle;
2033
2034         ZERO_STRUCT(r);
2035         r.in.hostname = &hostname;
2036         r.in.message = talloc(tctx, struct lsa_StringLarge);
2037         init_lsa_StringLarge(r.in.message, "spottyfood");
2038         r.in.force_apps = 1;
2039         r.in.timeout = 30;
2040         r.in.do_reboot = 1;
2041
2042         torture_assert_ntstatus_ok(tctx,
2043                                    dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2044                                    "InitiateSystemShutdown failed");
2045
2046         torture_assert_werr_ok(tctx, r.out.result,
2047                                "InitiateSystemShutdown failed");
2048
2049         return test_AbortSystemShutdown(b, tctx);
2050 }
2051
2052
2053 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2054                                           struct dcerpc_pipe *p)
2055 {
2056         struct winreg_InitiateSystemShutdownEx r;
2057         uint16_t hostname = 0x0;
2058         struct dcerpc_binding_handle *b = p->binding_handle;
2059
2060         ZERO_STRUCT(r);
2061         r.in.hostname = &hostname;
2062         r.in.message = talloc(tctx, struct lsa_StringLarge);
2063         init_lsa_StringLarge(r.in.message, "spottyfood");
2064         r.in.force_apps = 1;
2065         r.in.timeout = 30;
2066         r.in.do_reboot = 1;
2067         r.in.reason = 0;
2068
2069         torture_assert_ntstatus_ok(tctx,
2070                 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2071                 "InitiateSystemShutdownEx failed");
2072
2073         torture_assert_werr_ok(tctx, r.out.result,
2074                                "InitiateSystemShutdownEx failed");
2075
2076         return test_AbortSystemShutdown(b, tctx);
2077 }
2078 #define MAX_DEPTH 2             /* Only go this far down the tree */
2079
2080 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2081                      struct policy_handle *handle, int depth,
2082                      bool test_security)
2083 {
2084         struct dcerpc_binding_handle *b = p->binding_handle;
2085
2086         if (depth == MAX_DEPTH)
2087                 return true;
2088
2089         if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
2090         }
2091
2092         if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2093         }
2094
2095         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2096         }
2097
2098         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2099         }
2100
2101         if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
2102         }
2103
2104         test_CloseKey(b, tctx, handle);
2105
2106         return true;
2107 }
2108
2109 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2110                                  struct torture_context *tctx,
2111                                  struct policy_handle *handle)
2112 {
2113         const char *value_name = TEST_VALUE;
2114         uint32_t value = 0x12345678;
2115         uint64_t value2 = 0x12345678;
2116         const char *string = "torture";
2117         const char *array[2];
2118         DATA_BLOB blob;
2119         enum winreg_Type types[] = {
2120                 REG_DWORD,
2121                 REG_DWORD_BIG_ENDIAN,
2122                 REG_QWORD,
2123                 REG_BINARY,
2124                 REG_SZ,
2125                 REG_MULTI_SZ
2126         };
2127         int t;
2128
2129         array[0] = "array0";
2130         array[1] = NULL;
2131
2132         torture_comment(tctx, "Testing SetValue (standard formats)\n");
2133
2134         for (t=0; t < ARRAY_SIZE(types); t++) {
2135
2136                 enum winreg_Type w_type;
2137                 uint32_t w_size, w_length;
2138                 uint8_t *w_data;
2139
2140                 switch (types[t]) {
2141                 case REG_DWORD:
2142                 case REG_DWORD_BIG_ENDIAN:
2143                         blob = data_blob_talloc_zero(tctx, 4);
2144                         SIVAL(blob.data, 0, value);
2145                         break;
2146                 case REG_QWORD:
2147                         blob = data_blob_talloc_zero(tctx, 8);
2148                         SBVAL(blob.data, 0, value2);
2149                         break;
2150                 case REG_BINARY:
2151                         blob = data_blob_string_const("binary_blob");
2152                         break;
2153                 case REG_SZ:
2154                         torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2155                         break;
2156                 case REG_MULTI_SZ:
2157                         torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2158                         break;
2159                 default:
2160                         break;
2161                 }
2162
2163                 torture_assert(tctx,
2164                         test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2165                         "test_SetValue failed");
2166                 torture_assert(tctx,
2167                         test_QueryValue_full(b, tctx, handle, value_name, true),
2168                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2169                 torture_assert(tctx,
2170                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2171                         "test_winreg_QueryValue failed");
2172                 torture_assert(tctx,
2173                         test_DeleteValue(b, tctx, handle, value_name),
2174                         "test_DeleteValue failed");
2175
2176                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2177                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2178                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2179                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2180         }
2181
2182         torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2183
2184         return true;
2185 }
2186
2187 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2188                                  struct torture_context *tctx,
2189                                  struct policy_handle *handle)
2190 {
2191         DATA_BLOB blob;
2192         const char *values[] = {
2193                 "torture_value",
2194                 "torture value",
2195                 "torture,value",
2196                 "torture;value",
2197                 "torture/value",
2198                 "torture\\value",
2199                 "torture_value_name",
2200                 "torture value name",
2201                 "torture,value,name",
2202                 "torture;value;name",
2203                 "torture/value/name",
2204                 "torture\\value\\name",
2205         };
2206         int i;
2207
2208         torture_comment(tctx, "Testing SetValue (values)\n");
2209
2210         for (i=0; i < ARRAY_SIZE(values); i++) {
2211
2212                 enum winreg_Type w_type;
2213                 uint32_t w_size, w_length;
2214                 uint8_t *w_data;
2215
2216                 blob = data_blob_talloc(tctx, NULL, 32);
2217
2218                 generate_random_buffer(blob.data, 32);
2219
2220                 torture_assert(tctx,
2221                         test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2222                         "test_SetValue failed");
2223                 torture_assert(tctx,
2224                         test_QueryValue_full(b, tctx, handle, values[i], true),
2225                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2226                 torture_assert(tctx,
2227                         test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2228                         "test_winreg_QueryValue failed");
2229                 torture_assert(tctx,
2230                         test_DeleteValue(b, tctx, handle, values[i]),
2231                         "test_DeleteValue failed");
2232
2233                 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2234                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2235                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2236                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2237         }
2238
2239         torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2240
2241         return true;
2242 }
2243
2244 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2245
2246 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2247                                    struct torture_context *tctx,
2248                                    struct policy_handle *handle)
2249 {
2250         const char *value_name = TEST_VALUE;
2251         enum winreg_Type types[] = {
2252                 REG_NONE,
2253                 REG_SZ,
2254                 REG_EXPAND_SZ,
2255                 REG_BINARY,
2256                 REG_DWORD,
2257                 REG_DWORD_BIG_ENDIAN,
2258                 REG_LINK,
2259                 REG_MULTI_SZ,
2260                 REG_RESOURCE_LIST,
2261                 REG_FULL_RESOURCE_DESCRIPTOR,
2262                 REG_RESOURCE_REQUIREMENTS_LIST,
2263                 REG_QWORD,
2264                 12,
2265                 13,
2266                 14,
2267                 55,
2268                 123456,
2269                 653210,
2270                 __LINE__
2271         };
2272         int t, l;
2273
2274         if (torture_setting_bool(tctx, "samba4", false)) {
2275                 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2276         }
2277
2278         torture_comment(tctx, "Testing SetValue (extended formats)\n");
2279
2280         for (t=0; t < ARRAY_SIZE(types); t++) {
2281         for (l=0; l < 16; l++) {
2282
2283                 enum winreg_Type w_type;
2284                 uint32_t w_size, w_length;
2285                 uint8_t *w_data;
2286
2287                 uint32_t size;
2288                 uint8_t *data;
2289
2290                 size = l;
2291                 data = talloc_array(tctx, uint8_t, size);
2292
2293                 generate_random_buffer(data, size);
2294
2295                 torture_assert(tctx,
2296                         test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2297                         "test_SetValue failed");
2298
2299                 torture_assert(tctx,
2300                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2301                         "test_winreg_QueryValue failed");
2302
2303                 torture_assert(tctx,
2304                         test_DeleteValue(b, tctx, handle, value_name),
2305                         "test_DeleteValue failed");
2306
2307                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2308                 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2309                 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2310                 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2311         }
2312         }
2313
2314         torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2315
2316         return true;
2317 }
2318
2319 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2320                                  struct torture_context *tctx,
2321                                  struct policy_handle *handle)
2322 {
2323         const char *keys[] = {
2324                 "torture_key",
2325                 "torture key",
2326                 "torture,key",
2327                 "torture/key",
2328                 "torture\\key",
2329         };
2330         int i;
2331
2332         for (i=0; i < ARRAY_SIZE(keys); i++) {
2333
2334                 enum winreg_CreateAction action_taken;
2335                 struct policy_handle new_handle;
2336                 char *q, *tmp;
2337
2338                 torture_assert(tctx,
2339                         test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2340                                             REG_OPTION_NON_VOLATILE,
2341                                             SEC_FLAG_MAXIMUM_ALLOWED,
2342                                             NULL,
2343                                             WERR_OK,
2344                                             &action_taken,
2345                                             &new_handle),
2346                         talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2347
2348                 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2349
2350                 torture_assert(tctx,
2351                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2352                         "failed to delete key");
2353
2354                 torture_assert(tctx,
2355                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2356                         "failed 2nd delete key");
2357
2358                 tmp = talloc_strdup(tctx, keys[i]);
2359
2360                 q = strchr(tmp, '\\');
2361                 if (q != NULL) {
2362                         *q = '\0';
2363                         q++;
2364
2365                         torture_assert(tctx,
2366                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2367                                 "failed to delete key");
2368
2369                         torture_assert(tctx,
2370                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2371                                 "failed 2nd delete key");
2372                 }
2373         }
2374
2375         return true;
2376 }
2377
2378 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2379 #define VALUE_CURRENT_VERSION "CurrentVersion"
2380 #define VALUE_SYSTEM_ROOT "SystemRoot"
2381
2382 static bool test_HKLM_wellknown(struct torture_context *tctx,
2383                                 struct dcerpc_binding_handle *b,
2384                                 struct policy_handle *handle)
2385 {
2386         struct policy_handle newhandle;
2387         int i;
2388         struct {
2389                 const char *values[3];
2390                 uint32_t num_values;
2391                 bool existing_value;
2392                 const char *error_message;
2393         } multiple_values_tests[] = {
2394                 {
2395                         .values[0] = VALUE_CURRENT_VERSION,
2396                         .values[1] = NULL,
2397                         .values[2] = NULL,
2398                         .num_values = 1,
2399                         .existing_value = true
2400                 },{
2401                         .values[0] = VALUE_SYSTEM_ROOT,
2402                         .values[1] = NULL,
2403                         .values[2] = NULL,
2404                         .num_values = 1,
2405                         .existing_value = true
2406                 },{
2407                         .values[0] = VALUE_CURRENT_VERSION,
2408                         .values[1] = VALUE_SYSTEM_ROOT,
2409                         .values[2] = NULL,
2410                         .num_values = 2,
2411                         .existing_value = true
2412                 },{
2413                         .values[0] = VALUE_CURRENT_VERSION,
2414                         .values[1] = VALUE_SYSTEM_ROOT,
2415                         .values[2] = VALUE_CURRENT_VERSION,
2416                         .num_values = 3,
2417                         .existing_value = true
2418                 },{
2419                         .values[0] = VALUE_CURRENT_VERSION,
2420                         .values[1] = NULL,
2421                         .values[2] = VALUE_SYSTEM_ROOT,
2422                         .num_values = 3,
2423                         .existing_value = false
2424                 },{
2425                         .values[0] = VALUE_CURRENT_VERSION,
2426                         .values[1] = "",
2427                         .values[2] = VALUE_SYSTEM_ROOT,
2428                         .num_values = 3,
2429                         .existing_value = false
2430                 },{
2431                         .values[0] = "IDoNotExist",
2432                         .values[1] = NULL,
2433                         .values[2] = NULL,
2434                         .num_values = 1,
2435                         .existing_value = false
2436                 },{
2437                         .values[0] = "IDoNotExist",
2438                         .values[1] = VALUE_CURRENT_VERSION,
2439                         .values[2] = NULL,
2440                         .num_values = 2,
2441                         .existing_value = false
2442                 },{
2443                         .values[0] = VALUE_CURRENT_VERSION,
2444                         .values[1] = "IDoNotExist",
2445                         .values[2] = NULL,
2446                         .num_values = 2,
2447                         .existing_value = false
2448                 }
2449         };
2450
2451         /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2452         if (torture_setting_bool(tctx, "samba3", false)) {
2453                 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2454                                KEY_CURRENT_VERSION,
2455                                REG_OPTION_NON_VOLATILE,
2456                                KEY_QUERY_VALUE,
2457                                &newhandle,
2458                                WERR_OK),
2459                         "failed to open current version key");
2460         } else {
2461                 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2462                         "failed to open current version key");
2463         }
2464
2465         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2466                 "failed to query current version");
2467         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2468                 "succeeded to query nonexistent value");
2469         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2470                 "succeeded to query value with NULL name");
2471         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2472                 "succeeded to query nonexistent default value (\"\")");
2473
2474         if (torture_setting_bool(tctx, "samba4", false)) {
2475                 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2476                 goto close_key;
2477         }
2478
2479         for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2480                 const char *msg;
2481                 msg = talloc_asprintf(tctx,
2482                                 "failed to query %d %sexisting values\n",
2483                                         multiple_values_tests[i].num_values,
2484                                         multiple_values_tests[i].existing_value ? "":"non");
2485
2486                 torture_assert(tctx,
2487                         test_QueryMultipleValues_full(b, tctx, &newhandle,
2488                                                       multiple_values_tests[i].num_values,
2489                                                       multiple_values_tests[i].values,
2490                                                       multiple_values_tests[i].existing_value),
2491                         msg);
2492                 torture_assert(tctx,
2493                         test_QueryMultipleValues2_full(b, tctx, &newhandle,
2494                                                        multiple_values_tests[i].num_values,
2495                                                        multiple_values_tests[i].values,
2496                                                        multiple_values_tests[i].existing_value),
2497                         msg);
2498         }
2499
2500  close_key:
2501         torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2502                 "failed to close current version key");
2503
2504         return true;
2505 }
2506
2507 static bool test_OpenHive(struct torture_context *tctx,
2508                           struct dcerpc_binding_handle *b,
2509                           struct policy_handle *handle,
2510                           int hkey)
2511 {
2512         struct winreg_OpenHKLM r;
2513
2514         r.in.system_name = 0;
2515         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2516         r.out.handle = handle;
2517
2518         switch (hkey) {
2519         case HKEY_LOCAL_MACHINE:
2520                 torture_assert_ntstatus_ok(tctx,
2521                         dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2522                         "failed to open HKLM");
2523                 torture_assert_werr_ok(tctx, r.out.result,
2524                         "failed to open HKLM");
2525                 break;
2526         case HKEY_CURRENT_USER:
2527                 torture_assert_ntstatus_ok(tctx,
2528                         dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)&r),
2529                         "failed to open HKCU");
2530                 torture_assert_werr_ok(tctx, r.out.result,
2531                         "failed to open HKCU");
2532                 break;
2533         case HKEY_USERS:
2534                 torture_assert_ntstatus_ok(tctx,
2535                         dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)&r),
2536                         "failed to open HKU");
2537                 torture_assert_werr_ok(tctx, r.out.result,
2538                         "failed to open HKU");
2539                 break;
2540         case HKEY_CLASSES_ROOT:
2541                 torture_assert_ntstatus_ok(tctx,
2542                         dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)&r),
2543                         "failed to open HKCR");
2544                 torture_assert_werr_ok(tctx, r.out.result,
2545                         "failed to open HKCR");
2546                 break;
2547         default:
2548                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2549                 return false;
2550         }
2551
2552         return true;
2553 }
2554
2555 static bool test_volatile_keys(struct torture_context *tctx,
2556                                struct dcerpc_binding_handle *b,
2557                                struct policy_handle *handle,
2558                                int hkey)
2559 {
2560         struct policy_handle new_handle;
2561         enum winreg_CreateAction action_taken;
2562
2563         torture_comment(tctx, "Testing VOLATILE key\n");
2564
2565         test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2566
2567         torture_assert(tctx,
2568                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2569                                     REG_OPTION_VOLATILE,
2570                                     SEC_FLAG_MAXIMUM_ALLOWED,
2571                                     NULL,
2572                                     WERR_OK,
2573                                     &action_taken,
2574                                     &new_handle),
2575                 "failed to create REG_OPTION_VOLATILE type key");
2576
2577         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2578
2579         torture_assert(tctx,
2580                 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2581                                     REG_OPTION_NON_VOLATILE,
2582                                     SEC_FLAG_MAXIMUM_ALLOWED,
2583                                     NULL,
2584                                     WERR_CHILD_MUST_BE_VOLATILE,
2585                                     NULL,
2586                                     NULL),
2587                 "failed to fail create REG_OPTION_VOLATILE type key");
2588
2589         torture_assert(tctx,
2590                 test_CloseKey(b, tctx, &new_handle),
2591                 "failed to close");
2592
2593         torture_assert(tctx,
2594                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2595                                   REG_OPTION_NON_VOLATILE,
2596                                   SEC_FLAG_MAXIMUM_ALLOWED,
2597                                   &new_handle,
2598                                   WERR_OK),
2599                 "failed to open volatile key");
2600
2601         torture_assert(tctx,
2602                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2603                 "failed to delete key");
2604
2605         torture_assert(tctx,
2606                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2607                                     REG_OPTION_VOLATILE,
2608                                     SEC_FLAG_MAXIMUM_ALLOWED,
2609                                     NULL,
2610                                     WERR_OK,
2611                                     &action_taken,
2612                                     &new_handle),
2613                 "failed to create REG_OPTION_VOLATILE type key");
2614
2615         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2616
2617         torture_assert(tctx,
2618                 test_CloseKey(b, tctx, &new_handle),
2619                 "failed to close");
2620
2621         torture_assert(tctx,
2622                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2623                                   REG_OPTION_VOLATILE,
2624                                   SEC_FLAG_MAXIMUM_ALLOWED,
2625                                   &new_handle,
2626                                   WERR_OK),
2627                 "failed to open volatile key");
2628
2629         torture_assert(tctx,
2630                 test_CloseKey(b, tctx, &new_handle),
2631                 "failed to close");
2632
2633         torture_assert(tctx,
2634                 test_CloseKey(b, tctx, handle),
2635                 "failed to close");
2636
2637         torture_assert(tctx,
2638                 test_OpenHive(tctx, b, handle, hkey),
2639                 "failed top open hive");
2640
2641         torture_assert(tctx,
2642                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2643                                   REG_OPTION_VOLATILE,
2644                                   SEC_FLAG_MAXIMUM_ALLOWED,
2645                                   &new_handle,
2646                                   WERR_BADFILE),
2647                 "failed to open volatile key");
2648
2649         torture_assert(tctx,
2650                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2651                                   REG_OPTION_NON_VOLATILE,
2652                                   SEC_FLAG_MAXIMUM_ALLOWED,
2653                                   &new_handle,
2654                                   WERR_BADFILE),
2655                 "failed to open volatile key");
2656
2657         torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2658
2659         return true;
2660 }
2661
2662 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2663                                              int hkey,
2664                                              const char *sid_string,
2665                                              const char *path)
2666 {
2667         switch (hkey) {
2668         case HKEY_LOCAL_MACHINE:
2669                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2670         case HKEY_CURRENT_USER:
2671                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2672         case HKEY_USERS:
2673                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2674         case HKEY_CLASSES_ROOT:
2675                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2676         default:
2677                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2678                 return NULL;
2679         }
2680
2681         return NULL;
2682 }
2683
2684 static bool test_symlink_keys(struct torture_context *tctx,
2685                               struct dcerpc_binding_handle *b,
2686                               struct policy_handle *handle,
2687                               const char *key,
2688                               int hkey)
2689 {
2690         struct policy_handle new_handle;
2691         enum winreg_CreateAction action_taken;
2692         DATA_BLOB blob;
2693         uint32_t value = 42;
2694         const char *test_key_symlink_dest;
2695         const char *test_key_symlink;
2696         const char *kernel_mode_path;
2697
2698         /* disable until we know how to delete a symbolic link */
2699         torture_skip(tctx, "symlink test disabled");
2700
2701         torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2702
2703         /* create destination key with testvalue */
2704         test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2705                         key, TEST_KEY_SYMLINK);
2706         test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2707                         key, TEST_KEY_SYMLINK_DEST);
2708
2709         test_DeleteKey(b, tctx, handle, test_key_symlink);
2710
2711         torture_assert(tctx,
2712                 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2713                                     0,
2714                                     SEC_FLAG_MAXIMUM_ALLOWED,
2715                                     NULL,
2716                                     WERR_OK,
2717                                     &action_taken,
2718                                     &new_handle),
2719                 "failed to create symlink destination");
2720
2721         blob = data_blob_talloc_zero(tctx, 4);
2722         SIVAL(blob.data, 0, value);
2723
2724         torture_assert(tctx,
2725                 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2726                 "failed to create TestValue");
2727
2728         torture_assert(tctx,
2729                 test_CloseKey(b, tctx, &new_handle),
2730                 "failed to close");
2731
2732         /* create symlink */
2733
2734         torture_assert(tctx,
2735                 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2736                                     REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2737                                     SEC_FLAG_MAXIMUM_ALLOWED,
2738                                     NULL,
2739                                     WERR_OK,
2740                                     &action_taken,
2741                                     &new_handle),
2742                 "failed to create REG_OPTION_CREATE_LINK type key");
2743
2744         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2745
2746         kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2747
2748         torture_assert(tctx,
2749                 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2750                                       kernel_mode_path,
2751                                       strlen(kernel_mode_path), /* not NULL terminated */
2752                                       &blob.data, &blob.length,
2753                                       false),
2754                 "failed to convert");
2755
2756         torture_assert(tctx,
2757                 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2758                 "failed to create SymbolicLinkValue value");
2759
2760         torture_assert(tctx,
2761                 test_CloseKey(b, tctx, &new_handle),
2762                 "failed to close");
2763
2764         /* test follow symlink */
2765
2766         torture_assert(tctx,
2767                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2768                                   0,
2769                                   SEC_FLAG_MAXIMUM_ALLOWED,
2770                                   &new_handle,
2771                                   WERR_OK),
2772                 "failed to follow symlink key");
2773
2774         torture_assert(tctx,
2775                 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2776                 "failed to query value");
2777
2778         torture_assert(tctx,
2779                 test_CloseKey(b, tctx, &new_handle),
2780                 "failed to close");
2781
2782         /* delete link */
2783
2784         torture_assert(tctx,
2785                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2786                                   REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2787                                   SEC_FLAG_MAXIMUM_ALLOWED,
2788                                   &new_handle,
2789                                   WERR_OK),
2790                 "failed to open symlink key");
2791
2792         torture_assert(tctx,
2793                 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2794                 "failed to delete value SymbolicLinkValue");
2795
2796         torture_assert(tctx,
2797                 test_CloseKey(b, tctx, &new_handle),
2798                 "failed to close");
2799
2800         torture_assert(tctx,
2801                 test_DeleteKey(b, tctx, handle, test_key_symlink),
2802                 "failed to delete key");
2803
2804         /* delete destination */
2805
2806         torture_assert(tctx,
2807                 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2808                 "failed to delete key");
2809
2810         return true;
2811 }
2812
2813 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2814                                     struct dcerpc_binding_handle *b,
2815                                     struct policy_handle *handle,
2816                                     const char *key,
2817                                     int hkey)
2818 {
2819
2820         if (torture_setting_bool(tctx, "samba3", false) ||
2821             torture_setting_bool(tctx, "samba4", false)) {
2822                 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2823         }
2824
2825         torture_assert(tctx,
2826                 test_volatile_keys(tctx, b, handle, hkey),
2827                 "failed to test volatile keys");
2828
2829         torture_assert(tctx,
2830                 test_symlink_keys(tctx, b, handle, key, hkey),
2831                 "failed to test symlink keys");
2832
2833         return true;
2834 }
2835
2836 static bool test_key_base(struct torture_context *tctx,
2837                           struct dcerpc_binding_handle *b,
2838                           struct policy_handle *handle,
2839                           const char *base_key,
2840                           int hkey)
2841 {
2842         struct policy_handle newhandle;
2843         bool ret = true, created = false, deleted = false;
2844         bool created3 = false;
2845         const char *test_key1;
2846         const char *test_key3;
2847         const char *test_subkey;
2848
2849         test_Cleanup(b, tctx, handle, base_key);
2850
2851         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2852                 torture_comment(tctx,
2853                                 "CreateKey(%s) failed\n", base_key);
2854         }
2855
2856         test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2857
2858         if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2859                 torture_comment(tctx,
2860                                 "CreateKey failed - not considering a failure\n");
2861         } else {
2862                 created = true;
2863         }
2864
2865         if (created) {
2866                 if (!test_FlushKey(b, tctx, handle)) {
2867                         torture_comment(tctx, "FlushKey failed\n");
2868                         ret = false;
2869                 }
2870
2871                 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2872                         torture_fail(tctx,
2873                                      "CreateKey failed (OpenKey after Create didn't work)\n");
2874                 }
2875
2876                 if (hkey == HKEY_CURRENT_USER) {
2877                         torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2878                                 "simple SetValue test failed");
2879                         torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2880                                 "values SetValue test failed");
2881                         torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2882                                 "extended SetValue test failed");
2883                         torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2884                                 "keyname CreateKey test failed");
2885                 } else {
2886                         torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2887                                 "keytype test failed");
2888                 }
2889
2890                 if (!test_CloseKey(b, tctx, &newhandle)) {
2891                         torture_fail(tctx,
2892                                      "CreateKey failed (CloseKey after Open didn't work)\n");
2893                 }
2894
2895                 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2896                         torture_comment(tctx, "DeleteKey failed\n");
2897                         ret = false;
2898                 } else {
2899                         deleted = true;
2900                 }
2901
2902                 if (!test_FlushKey(b, tctx, handle)) {
2903                         torture_comment(tctx, "FlushKey failed\n");
2904                         ret = false;
2905                 }
2906
2907                 if (deleted) {
2908                         if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2909                                                REG_OPTION_NON_VOLATILE,
2910                                                SEC_FLAG_MAXIMUM_ALLOWED,
2911                                                &newhandle,
2912                                                WERR_BADFILE)) {
2913                                 torture_comment(tctx,
2914                                                 "DeleteKey failed (OpenKey after Delete "
2915                                                 "did not return WERR_BADFILE)\n");
2916                                 ret = false;
2917                         }
2918                 }
2919
2920                 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2921
2922                 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2923                         created3 = true;
2924                 }
2925
2926                 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2927
2928                 if (created3) {
2929                         if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2930                                 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2931                                         torture_comment(tctx, "DeleteKey failed\n");
2932                                         ret = false;
2933                                 }
2934                         }
2935
2936                         if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2937                                 torture_comment(tctx, "DeleteKey failed\n");
2938                                 ret = false;
2939                         }
2940                 }
2941         }
2942
2943         test_Cleanup(b, tctx, handle, base_key);
2944
2945         return ret;
2946 }
2947
2948 static bool test_key_base_sd(struct torture_context *tctx,
2949                              struct dcerpc_pipe *p,
2950                              struct policy_handle *handle,
2951                              const char *base_key)
2952 {
2953         struct policy_handle newhandle;
2954         bool ret = true, created2 = false, created4 = false;
2955         struct dcerpc_binding_handle *b = p->binding_handle;
2956         const char *test_key2;
2957         const char *test_key4;
2958
2959         torture_skip(tctx, "security descriptor test disabled\n");
2960
2961         if (torture_setting_bool(tctx, "samba3", false) ||
2962             torture_setting_bool(tctx, "samba4", false)) {
2963                 torture_skip(tctx, "skipping security descriptor tests against Samba");
2964         }
2965
2966         test_Cleanup(b, tctx, handle, base_key);
2967
2968         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2969                 torture_comment(tctx,
2970                                 "CreateKey(%s) failed\n", base_key);
2971         }
2972
2973         test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
2974
2975         if (test_CreateKey_sd(b, tctx, handle, test_key2,
2976                               NULL, &newhandle)) {
2977                 created2 = true;
2978         }
2979
2980         if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2981                 torture_comment(tctx, "CloseKey failed\n");
2982                 ret = false;
2983         }
2984
2985         test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
2986
2987         if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
2988                 created4 = true;
2989         }
2990
2991         if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2992                 torture_comment(tctx, "CloseKey failed\n");
2993                 ret = false;
2994         }
2995
2996         if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
2997                 ret = false;
2998         }
2999
3000         if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3001                 torture_comment(tctx, "DeleteKey failed\n");
3002                 ret = false;
3003         }
3004
3005         if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3006                 torture_comment(tctx, "DeleteKey failed\n");
3007                 ret = false;
3008         }
3009
3010         test_Cleanup(b, tctx, handle, base_key);
3011
3012         return ret;
3013 }
3014
3015 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3016                       void *userdata)
3017 {
3018         struct policy_handle handle;
3019         bool ret = true;
3020         struct winreg_OpenHKLM r;
3021         struct dcerpc_binding_handle *b = p->binding_handle;
3022         const char *torture_base_key;
3023         int hkey = 0;
3024
3025         winreg_open_fn open_fn = (winreg_open_fn)userdata;
3026
3027         r.in.system_name = 0;
3028         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3029         r.out.handle = &handle;
3030
3031         torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3032                                    "open");
3033
3034         if (!test_GetVersion(b, tctx, &handle)) {
3035                 torture_comment(tctx, "GetVersion failed\n");
3036                 ret = false;
3037         }
3038
3039         if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3040                 hkey = HKEY_LOCAL_MACHINE;
3041                 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3042         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3043                 hkey = HKEY_USERS;
3044                 torture_base_key = TEST_KEY_BASE;
3045         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3046                 hkey = HKEY_CLASSES_ROOT;
3047                 torture_base_key = TEST_KEY_BASE;
3048         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3049                 hkey = HKEY_CURRENT_USER;
3050                 torture_base_key = TEST_KEY_BASE;
3051         } else {
3052                 torture_fail(tctx, "unsupported hkey");
3053         }
3054
3055         if (hkey == HKEY_LOCAL_MACHINE) {
3056                 torture_assert(tctx,
3057                         test_HKLM_wellknown(tctx, b, &handle),
3058                         "failed to test HKLM wellknown keys");
3059         }
3060
3061         if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3062                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3063                                 torture_base_key);
3064                 ret = false;
3065         }
3066
3067         if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3068                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3069                                 torture_base_key);
3070                 ret = false;
3071         }
3072
3073         /* The HKCR hive has a very large fanout */
3074         if (hkey == HKEY_CLASSES_ROOT) {
3075                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3076                         ret = false;
3077                 }
3078         } else if (hkey == HKEY_LOCAL_MACHINE) {
3079                 /* FIXME we are not allowed to enum values in the HKLM root */
3080         } else {
3081                 if (!test_key(p, tctx, &handle, 0, false)) {
3082                         ret = false;
3083                 }
3084         }
3085
3086         return ret;
3087 }
3088
3089 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3090 {
3091         struct torture_rpc_tcase *tcase;
3092         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
3093         struct torture_test *test;
3094
3095         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3096                                                   &ndr_table_winreg);
3097
3098         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3099                                           test_InitiateSystemShutdown);
3100         test->dangerous = true;
3101
3102         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3103                                           test_InitiateSystemShutdownEx);
3104         test->dangerous = true;
3105
3106         torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3107                                       test_Open,
3108                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
3109         torture_rpc_tcase_add_test_ex(tcase, "HKU",
3110                                       test_Open,
3111                                       (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
3112         torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3113                                       test_Open,
3114                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
3115         torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3116                                       test_Open,
3117                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
3118
3119         return suite;
3120 }