s4-smbtorture: enable QueryMultipleValues{2} torture tests 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, "samba3", false) ||
2275             torture_setting_bool(tctx, "samba4", false)) {
2276                 torture_skip(tctx, "skipping extended SetValue test against Samba");
2277         }
2278
2279         torture_comment(tctx, "Testing SetValue (extended formats)\n");
2280
2281         for (t=0; t < ARRAY_SIZE(types); t++) {
2282         for (l=0; l < 32; l++) {
2283
2284                 enum winreg_Type w_type;
2285                 uint32_t w_size, w_length;
2286                 uint8_t *w_data;
2287
2288                 uint32_t size;
2289                 uint8_t *data;
2290
2291                 size = l;
2292                 data = talloc_array(tctx, uint8_t, size);
2293
2294                 generate_random_buffer(data, size);
2295
2296                 torture_assert(tctx,
2297                         test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2298                         "test_SetValue failed");
2299
2300                 torture_assert(tctx,
2301                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2302                         "test_winreg_QueryValue failed");
2303
2304                 torture_assert(tctx,
2305                         test_DeleteValue(b, tctx, handle, value_name),
2306                         "test_DeleteValue failed");
2307
2308                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2309                 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2310                 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2311                 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2312         }
2313         }
2314
2315         torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2316
2317         return true;
2318 }
2319
2320 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2321                                  struct torture_context *tctx,
2322                                  struct policy_handle *handle)
2323 {
2324         const char *keys[] = {
2325                 "torture_key",
2326                 "torture key",
2327                 "torture,key",
2328                 "torture/key",
2329                 "torture\\key",
2330         };
2331         int i;
2332
2333         for (i=0; i < ARRAY_SIZE(keys); i++) {
2334
2335                 enum winreg_CreateAction action_taken;
2336                 struct policy_handle new_handle;
2337                 char *q, *tmp;
2338
2339                 torture_assert(tctx,
2340                         test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2341                                             REG_OPTION_NON_VOLATILE,
2342                                             SEC_FLAG_MAXIMUM_ALLOWED,
2343                                             NULL,
2344                                             WERR_OK,
2345                                             &action_taken,
2346                                             &new_handle),
2347                         talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2348
2349                 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2350
2351                 torture_assert(tctx,
2352                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2353                         "failed to delete key");
2354
2355                 torture_assert(tctx,
2356                         test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2357                         "failed 2nd delete key");
2358
2359                 tmp = talloc_strdup(tctx, keys[i]);
2360
2361                 q = strchr(tmp, '\\');
2362                 if (q != NULL) {
2363                         *q = '\0';
2364                         q++;
2365
2366                         torture_assert(tctx,
2367                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2368                                 "failed to delete key");
2369
2370                         torture_assert(tctx,
2371                                 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2372                                 "failed 2nd delete key");
2373                 }
2374         }
2375
2376         return true;
2377 }
2378
2379 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2380 #define VALUE_CURRENT_VERSION "CurrentVersion"
2381 #define VALUE_SYSTEM_ROOT "SystemRoot"
2382
2383 static bool test_HKLM_wellknown(struct torture_context *tctx,
2384                                 struct dcerpc_binding_handle *b,
2385                                 struct policy_handle *handle)
2386 {
2387         struct policy_handle newhandle;
2388         int i;
2389         struct {
2390                 const char *values[3];
2391                 uint32_t num_values;
2392                 bool existing_value;
2393                 const char *error_message;
2394         } multiple_values_tests[] = {
2395                 {
2396                         .values[0] = VALUE_CURRENT_VERSION,
2397                         .values[1] = NULL,
2398                         .values[2] = NULL,
2399                         .num_values = 1,
2400                         .existing_value = true
2401                 },{
2402                         .values[0] = VALUE_SYSTEM_ROOT,
2403                         .values[1] = NULL,
2404                         .values[2] = NULL,
2405                         .num_values = 1,
2406                         .existing_value = true
2407                 },{
2408                         .values[0] = VALUE_CURRENT_VERSION,
2409                         .values[1] = VALUE_SYSTEM_ROOT,
2410                         .values[2] = NULL,
2411                         .num_values = 2,
2412                         .existing_value = true
2413                 },{
2414                         .values[0] = VALUE_CURRENT_VERSION,
2415                         .values[1] = VALUE_SYSTEM_ROOT,
2416                         .values[2] = VALUE_CURRENT_VERSION,
2417                         .num_values = 3,
2418                         .existing_value = true
2419                 },{
2420                         .values[0] = VALUE_CURRENT_VERSION,
2421                         .values[1] = NULL,
2422                         .values[2] = VALUE_SYSTEM_ROOT,
2423                         .num_values = 3,
2424                         .existing_value = false
2425                 },{
2426                         .values[0] = VALUE_CURRENT_VERSION,
2427                         .values[1] = "",
2428                         .values[2] = VALUE_SYSTEM_ROOT,
2429                         .num_values = 3,
2430                         .existing_value = false
2431                 },{
2432                         .values[0] = "IDoNotExist",
2433                         .values[1] = NULL,
2434                         .values[2] = NULL,
2435                         .num_values = 1,
2436                         .existing_value = false
2437                 },{
2438                         .values[0] = "IDoNotExist",
2439                         .values[1] = VALUE_CURRENT_VERSION,
2440                         .values[2] = NULL,
2441                         .num_values = 2,
2442                         .existing_value = false
2443                 },{
2444                         .values[0] = VALUE_CURRENT_VERSION,
2445                         .values[1] = "IDoNotExist",
2446                         .values[2] = NULL,
2447                         .num_values = 2,
2448                         .existing_value = false
2449                 }
2450         };
2451
2452         /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2453         if (torture_setting_bool(tctx, "samba3", false)) {
2454                 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2455                                KEY_CURRENT_VERSION,
2456                                REG_OPTION_NON_VOLATILE,
2457                                KEY_QUERY_VALUE,
2458                                &newhandle,
2459                                WERR_OK),
2460                         "failed to open current version key");
2461         } else {
2462                 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2463                         "failed to open current version key");
2464         }
2465
2466         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2467                 "failed to query current version");
2468         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2469                 "succeeded to query nonexistent value");
2470         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2471                 "succeeded to query value with NULL name");
2472         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2473                 "succeeded to query nonexistent default value (\"\")");
2474
2475         if (torture_setting_bool(tctx, "samba4", false)) {
2476                 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2477                 goto close_key;
2478         }
2479
2480         for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2481                 const char *msg;
2482                 msg = talloc_asprintf(tctx,
2483                                 "failed to query %d %sexisting values\n",
2484                                         multiple_values_tests[i].num_values,
2485                                         multiple_values_tests[i].existing_value ? "":"non");
2486
2487                 torture_assert(tctx,
2488                         test_QueryMultipleValues_full(b, tctx, &newhandle,
2489                                                       multiple_values_tests[i].num_values,
2490                                                       multiple_values_tests[i].values,
2491                                                       multiple_values_tests[i].existing_value),
2492                         msg);
2493                 torture_assert(tctx,
2494                         test_QueryMultipleValues2_full(b, tctx, &newhandle,
2495                                                        multiple_values_tests[i].num_values,
2496                                                        multiple_values_tests[i].values,
2497                                                        multiple_values_tests[i].existing_value),
2498                         msg);
2499         }
2500
2501  close_key:
2502         torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2503                 "failed to close current version key");
2504
2505         return true;
2506 }
2507
2508 static bool test_OpenHive(struct torture_context *tctx,
2509                           struct dcerpc_binding_handle *b,
2510                           struct policy_handle *handle,
2511                           int hkey)
2512 {
2513         struct winreg_OpenHKLM r;
2514
2515         r.in.system_name = 0;
2516         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2517         r.out.handle = handle;
2518
2519         switch (hkey) {
2520         case HKEY_LOCAL_MACHINE:
2521                 torture_assert_ntstatus_ok(tctx,
2522                         dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2523                         "failed to open HKLM");
2524                 torture_assert_werr_ok(tctx, r.out.result,
2525                         "failed to open HKLM");
2526                 break;
2527         case HKEY_CURRENT_USER:
2528                 torture_assert_ntstatus_ok(tctx,
2529                         dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)&r),
2530                         "failed to open HKCU");
2531                 torture_assert_werr_ok(tctx, r.out.result,
2532                         "failed to open HKCU");
2533                 break;
2534         case HKEY_USERS:
2535                 torture_assert_ntstatus_ok(tctx,
2536                         dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)&r),
2537                         "failed to open HKU");
2538                 torture_assert_werr_ok(tctx, r.out.result,
2539                         "failed to open HKU");
2540                 break;
2541         case HKEY_CLASSES_ROOT:
2542                 torture_assert_ntstatus_ok(tctx,
2543                         dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)&r),
2544                         "failed to open HKCR");
2545                 torture_assert_werr_ok(tctx, r.out.result,
2546                         "failed to open HKCR");
2547                 break;
2548         default:
2549                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2550                 return false;
2551         }
2552
2553         return true;
2554 }
2555
2556 static bool test_volatile_keys(struct torture_context *tctx,
2557                                struct dcerpc_binding_handle *b,
2558                                struct policy_handle *handle,
2559                                int hkey)
2560 {
2561         struct policy_handle new_handle;
2562         enum winreg_CreateAction action_taken;
2563
2564         torture_comment(tctx, "Testing VOLATILE key\n");
2565
2566         test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2567
2568         torture_assert(tctx,
2569                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2570                                     REG_OPTION_VOLATILE,
2571                                     SEC_FLAG_MAXIMUM_ALLOWED,
2572                                     NULL,
2573                                     WERR_OK,
2574                                     &action_taken,
2575                                     &new_handle),
2576                 "failed to create REG_OPTION_VOLATILE type key");
2577
2578         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2579
2580         torture_assert(tctx,
2581                 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2582                                     REG_OPTION_NON_VOLATILE,
2583                                     SEC_FLAG_MAXIMUM_ALLOWED,
2584                                     NULL,
2585                                     WERR_CHILD_MUST_BE_VOLATILE,
2586                                     NULL,
2587                                     NULL),
2588                 "failed to fail create REG_OPTION_VOLATILE type key");
2589
2590         torture_assert(tctx,
2591                 test_CloseKey(b, tctx, &new_handle),
2592                 "failed to close");
2593
2594         torture_assert(tctx,
2595                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2596                                   REG_OPTION_NON_VOLATILE,
2597                                   SEC_FLAG_MAXIMUM_ALLOWED,
2598                                   &new_handle,
2599                                   WERR_OK),
2600                 "failed to open volatile key");
2601
2602         torture_assert(tctx,
2603                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2604                 "failed to delete key");
2605
2606         torture_assert(tctx,
2607                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2608                                     REG_OPTION_VOLATILE,
2609                                     SEC_FLAG_MAXIMUM_ALLOWED,
2610                                     NULL,
2611                                     WERR_OK,
2612                                     &action_taken,
2613                                     &new_handle),
2614                 "failed to create REG_OPTION_VOLATILE type key");
2615
2616         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2617
2618         torture_assert(tctx,
2619                 test_CloseKey(b, tctx, &new_handle),
2620                 "failed to close");
2621
2622         torture_assert(tctx,
2623                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2624                                   REG_OPTION_VOLATILE,
2625                                   SEC_FLAG_MAXIMUM_ALLOWED,
2626                                   &new_handle,
2627                                   WERR_OK),
2628                 "failed to open volatile key");
2629
2630         torture_assert(tctx,
2631                 test_CloseKey(b, tctx, &new_handle),
2632                 "failed to close");
2633
2634         torture_assert(tctx,
2635                 test_CloseKey(b, tctx, handle),
2636                 "failed to close");
2637
2638         torture_assert(tctx,
2639                 test_OpenHive(tctx, b, handle, hkey),
2640                 "failed top open hive");
2641
2642         torture_assert(tctx,
2643                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2644                                   REG_OPTION_VOLATILE,
2645                                   SEC_FLAG_MAXIMUM_ALLOWED,
2646                                   &new_handle,
2647                                   WERR_BADFILE),
2648                 "failed to open volatile key");
2649
2650         torture_assert(tctx,
2651                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2652                                   REG_OPTION_NON_VOLATILE,
2653                                   SEC_FLAG_MAXIMUM_ALLOWED,
2654                                   &new_handle,
2655                                   WERR_BADFILE),
2656                 "failed to open volatile key");
2657
2658         torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2659
2660         return true;
2661 }
2662
2663 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2664                                              int hkey,
2665                                              const char *sid_string,
2666                                              const char *path)
2667 {
2668         switch (hkey) {
2669         case HKEY_LOCAL_MACHINE:
2670                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2671         case HKEY_CURRENT_USER:
2672                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2673         case HKEY_USERS:
2674                 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2675         case HKEY_CLASSES_ROOT:
2676                 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2677         default:
2678                 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2679                 return NULL;
2680         }
2681
2682         return NULL;
2683 }
2684
2685 static bool test_symlink_keys(struct torture_context *tctx,
2686                               struct dcerpc_binding_handle *b,
2687                               struct policy_handle *handle,
2688                               const char *key,
2689                               int hkey)
2690 {
2691         struct policy_handle new_handle;
2692         enum winreg_CreateAction action_taken;
2693         DATA_BLOB blob;
2694         uint32_t value = 42;
2695         const char *test_key_symlink_dest;
2696         const char *test_key_symlink;
2697         const char *kernel_mode_path;
2698
2699         /* disable until we know how to delete a symbolic link */
2700         torture_skip(tctx, "symlink test disabled");
2701
2702         torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2703
2704         /* create destination key with testvalue */
2705         test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2706                         key, TEST_KEY_SYMLINK);
2707         test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2708                         key, TEST_KEY_SYMLINK_DEST);
2709
2710         test_DeleteKey(b, tctx, handle, test_key_symlink);
2711
2712         torture_assert(tctx,
2713                 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2714                                     0,
2715                                     SEC_FLAG_MAXIMUM_ALLOWED,
2716                                     NULL,
2717                                     WERR_OK,
2718                                     &action_taken,
2719                                     &new_handle),
2720                 "failed to create symlink destination");
2721
2722         blob = data_blob_talloc_zero(tctx, 4);
2723         SIVAL(blob.data, 0, value);
2724
2725         torture_assert(tctx,
2726                 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2727                 "failed to create TestValue");
2728
2729         torture_assert(tctx,
2730                 test_CloseKey(b, tctx, &new_handle),
2731                 "failed to close");
2732
2733         /* create symlink */
2734
2735         torture_assert(tctx,
2736                 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2737                                     REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2738                                     SEC_FLAG_MAXIMUM_ALLOWED,
2739                                     NULL,
2740                                     WERR_OK,
2741                                     &action_taken,
2742                                     &new_handle),
2743                 "failed to create REG_OPTION_CREATE_LINK type key");
2744
2745         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2746
2747         kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2748
2749         torture_assert(tctx,
2750                 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2751                                       kernel_mode_path,
2752                                       strlen(kernel_mode_path), /* not NULL terminated */
2753                                       &blob.data, &blob.length,
2754                                       false),
2755                 "failed to convert");
2756
2757         torture_assert(tctx,
2758                 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2759                 "failed to create SymbolicLinkValue value");
2760
2761         torture_assert(tctx,
2762                 test_CloseKey(b, tctx, &new_handle),
2763                 "failed to close");
2764
2765         /* test follow symlink */
2766
2767         torture_assert(tctx,
2768                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2769                                   0,
2770                                   SEC_FLAG_MAXIMUM_ALLOWED,
2771                                   &new_handle,
2772                                   WERR_OK),
2773                 "failed to follow symlink key");
2774
2775         torture_assert(tctx,
2776                 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2777                 "failed to query value");
2778
2779         torture_assert(tctx,
2780                 test_CloseKey(b, tctx, &new_handle),
2781                 "failed to close");
2782
2783         /* delete link */
2784
2785         torture_assert(tctx,
2786                 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2787                                   REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2788                                   SEC_FLAG_MAXIMUM_ALLOWED,
2789                                   &new_handle,
2790                                   WERR_OK),
2791                 "failed to open symlink key");
2792
2793         torture_assert(tctx,
2794                 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2795                 "failed to delete value SymbolicLinkValue");
2796
2797         torture_assert(tctx,
2798                 test_CloseKey(b, tctx, &new_handle),
2799                 "failed to close");
2800
2801         torture_assert(tctx,
2802                 test_DeleteKey(b, tctx, handle, test_key_symlink),
2803                 "failed to delete key");
2804
2805         /* delete destination */
2806
2807         torture_assert(tctx,
2808                 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2809                 "failed to delete key");
2810
2811         return true;
2812 }
2813
2814 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2815                                     struct dcerpc_binding_handle *b,
2816                                     struct policy_handle *handle,
2817                                     const char *key,
2818                                     int hkey)
2819 {
2820
2821         if (torture_setting_bool(tctx, "samba3", false) ||
2822             torture_setting_bool(tctx, "samba4", false)) {
2823                 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2824         }
2825
2826         torture_assert(tctx,
2827                 test_volatile_keys(tctx, b, handle, hkey),
2828                 "failed to test volatile keys");
2829
2830         torture_assert(tctx,
2831                 test_symlink_keys(tctx, b, handle, key, hkey),
2832                 "failed to test symlink keys");
2833
2834         return true;
2835 }
2836
2837 static bool test_key_base(struct torture_context *tctx,
2838                           struct dcerpc_binding_handle *b,
2839                           struct policy_handle *handle,
2840                           const char *base_key,
2841                           int hkey)
2842 {
2843         struct policy_handle newhandle;
2844         bool ret = true, created = false, deleted = false;
2845         bool created3 = false;
2846         const char *test_key1;
2847         const char *test_key3;
2848         const char *test_subkey;
2849
2850         test_Cleanup(b, tctx, handle, base_key);
2851
2852         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2853                 torture_comment(tctx,
2854                                 "CreateKey(%s) failed\n", base_key);
2855         }
2856
2857         test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2858
2859         if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2860                 torture_comment(tctx,
2861                                 "CreateKey failed - not considering a failure\n");
2862         } else {
2863                 created = true;
2864         }
2865
2866         if (created) {
2867                 if (!test_FlushKey(b, tctx, handle)) {
2868                         torture_comment(tctx, "FlushKey failed\n");
2869                         ret = false;
2870                 }
2871
2872                 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2873                         torture_fail(tctx,
2874                                      "CreateKey failed (OpenKey after Create didn't work)\n");
2875                 }
2876
2877                 if (hkey == HKEY_CURRENT_USER) {
2878                         torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2879                                 "simple SetValue test failed");
2880                         torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2881                                 "values SetValue test failed");
2882                         torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2883                                 "extended SetValue test failed");
2884                         torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2885                                 "keyname CreateKey test failed");
2886                 } else {
2887                         torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2888                                 "keytype test failed");
2889                 }
2890
2891                 if (!test_CloseKey(b, tctx, &newhandle)) {
2892                         torture_fail(tctx,
2893                                      "CreateKey failed (CloseKey after Open didn't work)\n");
2894                 }
2895
2896                 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2897                         torture_comment(tctx, "DeleteKey failed\n");
2898                         ret = false;
2899                 } else {
2900                         deleted = true;
2901                 }
2902
2903                 if (!test_FlushKey(b, tctx, handle)) {
2904                         torture_comment(tctx, "FlushKey failed\n");
2905                         ret = false;
2906                 }
2907
2908                 if (deleted) {
2909                         if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2910                                                REG_OPTION_NON_VOLATILE,
2911                                                SEC_FLAG_MAXIMUM_ALLOWED,
2912                                                &newhandle,
2913                                                WERR_BADFILE)) {
2914                                 torture_comment(tctx,
2915                                                 "DeleteKey failed (OpenKey after Delete "
2916                                                 "did not return WERR_BADFILE)\n");
2917                                 ret = false;
2918                         }
2919                 }
2920
2921                 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2922
2923                 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2924                         created3 = true;
2925                 }
2926
2927                 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2928
2929                 if (created3) {
2930                         if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2931                                 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2932                                         torture_comment(tctx, "DeleteKey failed\n");
2933                                         ret = false;
2934                                 }
2935                         }
2936
2937                         if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2938                                 torture_comment(tctx, "DeleteKey failed\n");
2939                                 ret = false;
2940                         }
2941                 }
2942         }
2943
2944         test_Cleanup(b, tctx, handle, base_key);
2945
2946         return ret;
2947 }
2948
2949 static bool test_key_base_sd(struct torture_context *tctx,
2950                              struct dcerpc_pipe *p,
2951                              struct policy_handle *handle,
2952                              const char *base_key)
2953 {
2954         struct policy_handle newhandle;
2955         bool ret = true, created2 = false, created4 = false;
2956         struct dcerpc_binding_handle *b = p->binding_handle;
2957         const char *test_key2;
2958         const char *test_key4;
2959
2960         torture_skip(tctx, "security descriptor test disabled\n");
2961
2962         if (torture_setting_bool(tctx, "samba3", false) ||
2963             torture_setting_bool(tctx, "samba4", false)) {
2964                 torture_skip(tctx, "skipping security descriptor tests against Samba");
2965         }
2966
2967         test_Cleanup(b, tctx, handle, base_key);
2968
2969         if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2970                 torture_comment(tctx,
2971                                 "CreateKey(%s) failed\n", base_key);
2972         }
2973
2974         test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
2975
2976         if (test_CreateKey_sd(b, tctx, handle, test_key2,
2977                               NULL, &newhandle)) {
2978                 created2 = true;
2979         }
2980
2981         if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2982                 torture_comment(tctx, "CloseKey failed\n");
2983                 ret = false;
2984         }
2985
2986         test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
2987
2988         if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
2989                 created4 = true;
2990         }
2991
2992         if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2993                 torture_comment(tctx, "CloseKey failed\n");
2994                 ret = false;
2995         }
2996
2997         if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
2998                 ret = false;
2999         }
3000
3001         if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3002                 torture_comment(tctx, "DeleteKey failed\n");
3003                 ret = false;
3004         }
3005
3006         if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3007                 torture_comment(tctx, "DeleteKey failed\n");
3008                 ret = false;
3009         }
3010
3011         test_Cleanup(b, tctx, handle, base_key);
3012
3013         return ret;
3014 }
3015
3016 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3017                       void *userdata)
3018 {
3019         struct policy_handle handle;
3020         bool ret = true;
3021         struct winreg_OpenHKLM r;
3022         struct dcerpc_binding_handle *b = p->binding_handle;
3023         const char *torture_base_key;
3024         int hkey = 0;
3025
3026         winreg_open_fn open_fn = (winreg_open_fn)userdata;
3027
3028         r.in.system_name = 0;
3029         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3030         r.out.handle = &handle;
3031
3032         torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3033                                    "open");
3034
3035         if (!test_GetVersion(b, tctx, &handle)) {
3036                 torture_comment(tctx, "GetVersion failed\n");
3037                 ret = false;
3038         }
3039
3040         if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3041                 hkey = HKEY_LOCAL_MACHINE;
3042                 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3043         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3044                 hkey = HKEY_USERS;
3045                 torture_base_key = TEST_KEY_BASE;
3046         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3047                 hkey = HKEY_CLASSES_ROOT;
3048                 torture_base_key = TEST_KEY_BASE;
3049         } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3050                 hkey = HKEY_CURRENT_USER;
3051                 torture_base_key = TEST_KEY_BASE;
3052         } else {
3053                 torture_fail(tctx, "unsupported hkey");
3054         }
3055
3056         if (hkey == HKEY_LOCAL_MACHINE) {
3057                 torture_assert(tctx,
3058                         test_HKLM_wellknown(tctx, b, &handle),
3059                         "failed to test HKLM wellknown keys");
3060         }
3061
3062         if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3063                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3064                                 torture_base_key);
3065                 ret = false;
3066         }
3067
3068         if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3069                 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3070                                 torture_base_key);
3071                 ret = false;
3072         }
3073
3074         /* The HKCR hive has a very large fanout */
3075         if (hkey == HKEY_CLASSES_ROOT) {
3076                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3077                         ret = false;
3078                 }
3079         } else if (hkey == HKEY_LOCAL_MACHINE) {
3080                 /* FIXME we are not allowed to enum values in the HKLM root */
3081         } else {
3082                 if (!test_key(p, tctx, &handle, 0, false)) {
3083                         ret = false;
3084                 }
3085         }
3086
3087         return ret;
3088 }
3089
3090 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3091 {
3092         struct torture_rpc_tcase *tcase;
3093         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
3094         struct torture_test *test;
3095
3096         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3097                                                   &ndr_table_winreg);
3098
3099         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3100                                           test_InitiateSystemShutdown);
3101         test->dangerous = true;
3102
3103         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3104                                           test_InitiateSystemShutdownEx);
3105         test->dangerous = true;
3106
3107         torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3108                                       test_Open,
3109                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
3110         torture_rpc_tcase_add_test_ex(tcase, "HKU",
3111                                       test_Open,
3112                                       (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
3113         torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3114                                       test_Open,
3115                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
3116         torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3117                                       test_Open,
3118                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
3119
3120         return suite;
3121 }