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