Finish removal of iconv_convenience in public API's.
[bbaumbach/samba-autobuild/.git] / source4 / torture / rpc / winreg.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for winreg rpc operations
4
5    Copyright (C) Tim Potter 2003
6    Copyright (C) Jelmer Vernooij 2004-2007
7    Copyright (C) G√ľnther Deschner 2007
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "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 "smbtorture test"
32 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
33 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
34 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
35 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
36 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
37 #define TEST_SUBKEY_SD  TEST_KEY4 "\\subkey_sd"
38 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\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
44 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
45
46 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
47 {
48         name->string = s;
49 }
50
51 static void init_winreg_String(struct winreg_String *name, const char *s)
52 {
53         name->name = s;
54         if (s) {
55                 name->name_len = 2 * (strlen_m(s) + 1);
56                 name->name_size = name->name_len;
57         } else {
58                 name->name_len = 0;
59                 name->name_size = 0;
60         }
61 }
62
63 static bool test_GetVersion(struct dcerpc_binding_handle *b,
64                             struct torture_context *tctx,
65                             struct policy_handle *handle)
66 {
67         struct winreg_GetVersion r;
68         uint32_t v;
69
70         torture_comment(tctx, "Testing GetVersion\n");
71
72         ZERO_STRUCT(r);
73         r.in.handle = handle;
74         r.out.version = &v;
75
76         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
77                                    "GetVersion failed");
78
79         torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
80
81         return true;
82 }
83
84 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
85                                       struct torture_context *tctx,
86                                       struct policy_handle *handle)
87 {
88         struct winreg_NotifyChangeKeyValue r;
89
90         ZERO_STRUCT(r);
91         r.in.handle = handle;
92         r.in.watch_subtree = true;
93         r.in.notify_filter = 0;
94         r.in.unknown = r.in.unknown2 = 0;
95         init_winreg_String(&r.in.string1, NULL);
96         init_winreg_String(&r.in.string2, NULL);
97
98         torture_assert_ntstatus_ok(tctx,
99                                    dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
100                                    "NotifyChangeKeyValue failed");
101
102         if (!W_ERROR_IS_OK(r.out.result)) {
103                 torture_comment(tctx,
104                                 "NotifyChangeKeyValue failed - %s - not considering\n",
105                                 win_errstr(r.out.result));
106                 return true;
107         }
108
109         return true;
110 }
111
112 static bool test_CreateKey_opts(struct torture_context *tctx,
113                                 struct dcerpc_binding_handle *b,
114                                 struct policy_handle *handle,
115                                 const char *name,
116                                 const char *kclass,
117                                 uint32_t options,
118                                 uint32_t access_mask,
119                                 struct winreg_SecBuf *secdesc,
120                                 WERROR expected_result,
121                                 enum winreg_CreateAction *action_taken_p,
122                                 struct policy_handle *new_handle_p)
123 {
124         struct winreg_CreateKey r;
125         struct policy_handle newhandle;
126         enum winreg_CreateAction action_taken = 0;
127
128         torture_comment(tctx, "Testing CreateKey(%s)\n", name);
129
130         ZERO_STRUCT(r);
131         r.in.handle = handle;
132         init_winreg_String(&r.in.name, name);
133         init_winreg_String(&r.in.keyclass, kclass);
134         r.in.options = options;
135         r.in.access_mask = access_mask;
136         r.in.action_taken = &action_taken;
137         r.in.secdesc = secdesc;
138         r.out.new_handle = &newhandle;
139         r.out.action_taken = &action_taken;
140
141         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
142                                    "CreateKey failed");
143
144         torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
145
146         if (new_handle_p) {
147                 *new_handle_p = newhandle;
148         }
149         if (action_taken_p) {
150                 *action_taken_p = *r.out.action_taken;
151         }
152
153         return true;
154 }
155
156 static bool test_CreateKey(struct dcerpc_binding_handle *b,
157                            struct torture_context *tctx,
158                            struct policy_handle *handle, const char *name,
159                            const char *kclass)
160 {
161         return test_CreateKey_opts(tctx, b, handle, name, kclass,
162                                    REG_OPTION_NON_VOLATILE,
163                                    SEC_FLAG_MAXIMUM_ALLOWED,
164                                    NULL, /* secdesc */
165                                    WERR_OK,
166                                    NULL, /* action_taken */
167                                    NULL /* new_handle */);
168 }
169
170 /*
171   createkey testing with a SD
172 */
173 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
174                               struct torture_context *tctx,
175                               struct policy_handle *handle, const char *name,
176                               const char *kclass,
177                               struct policy_handle *newhandle)
178 {
179         struct winreg_CreateKey r;
180         enum winreg_CreateAction action_taken = 0;
181         struct security_descriptor *sd;
182         DATA_BLOB sdblob;
183         struct winreg_SecBuf secbuf;
184
185         sd = security_descriptor_dacl_create(tctx,
186                                         0,
187                                         NULL, NULL,
188                                         SID_NT_AUTHENTICATED_USERS,
189                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
190                                         SEC_GENERIC_ALL,
191                                         SEC_ACE_FLAG_OBJECT_INHERIT |
192                                         SEC_ACE_FLAG_CONTAINER_INHERIT,
193                                         NULL);
194
195         torture_assert_ndr_success(tctx,
196                 ndr_push_struct_blob(&sdblob, tctx, sd,
197                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
198                                      "Failed to push security_descriptor ?!\n");
199
200         secbuf.sd.data = sdblob.data;
201         secbuf.sd.len = sdblob.length;
202         secbuf.sd.size = sdblob.length;
203         secbuf.length = sdblob.length-10;
204         secbuf.inherit = 0;
205
206         ZERO_STRUCT(r);
207         r.in.handle = handle;
208         r.out.new_handle = newhandle;
209         init_winreg_String(&r.in.name, name);
210         init_winreg_String(&r.in.keyclass, kclass);
211         r.in.options = 0x0;
212         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
213         r.in.action_taken = r.out.action_taken = &action_taken;
214         r.in.secdesc = &secbuf;
215
216         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
217                                    "CreateKey with sd failed");
218
219         torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
220
221         return true;
222 }
223
224 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
225                                  struct torture_context *tctx,
226                                  struct policy_handle *handle,
227                                  uint32_t *sec_info_ptr,
228                                  WERROR get_werr,
229                                  struct security_descriptor **sd_out)
230 {
231         struct winreg_GetKeySecurity r;
232         struct security_descriptor *sd = NULL;
233         uint32_t sec_info;
234         DATA_BLOB sdblob;
235         struct dcerpc_binding_handle *b = p->binding_handle;
236
237         if (sec_info_ptr) {
238                 sec_info = *sec_info_ptr;
239         } else {
240                 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
241         }
242
243         ZERO_STRUCT(r);
244
245         r.in.handle = handle;
246         r.in.sec_info = sec_info;
247         r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
248         r.in.sd->size = 0x1000;
249
250         torture_assert_ntstatus_ok(tctx,
251                                    dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
252                                    "GetKeySecurity failed");
253
254         torture_assert_werr_equal(tctx, r.out.result, get_werr,
255                                   "GetKeySecurity failed");
256
257         sdblob.data = r.out.sd->data;
258         sdblob.length = r.out.sd->len;
259
260         sd = talloc_zero(tctx, struct security_descriptor);
261
262         torture_assert_ndr_success(tctx,
263                 ndr_pull_struct_blob(&sdblob, tctx, sd,
264                                      (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
265                                      "pull_security_descriptor failed");
266
267         if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
268                 NDR_PRINT_DEBUG(security_descriptor, sd);
269         }
270
271         if (sd_out) {
272                 *sd_out = sd;
273         } else {
274                 talloc_free(sd);
275         }
276
277         return true;
278 }
279
280 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
281                                 struct torture_context *tctx,
282                                 struct policy_handle *handle,
283                                 struct security_descriptor **sd_out)
284 {
285         return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
286 }
287
288 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
289                                  struct torture_context *tctx,
290                                  struct policy_handle *handle,
291                                  uint32_t *sec_info_ptr,
292                                  struct security_descriptor *sd,
293                                  WERROR werr)
294 {
295         struct winreg_SetKeySecurity r;
296         struct KeySecurityData *sdata = NULL;
297         DATA_BLOB sdblob;
298         uint32_t sec_info;
299         struct dcerpc_binding_handle *b = p->binding_handle;
300
301         ZERO_STRUCT(r);
302
303         if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
304                 NDR_PRINT_DEBUG(security_descriptor, sd);
305         }
306
307         torture_assert_ndr_success(tctx,
308                 ndr_push_struct_blob(&sdblob, tctx, sd,
309                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
310                                      "push_security_descriptor failed");
311
312         sdata = talloc_zero(tctx, struct KeySecurityData);
313         sdata->data = sdblob.data;
314         sdata->size = sdblob.length;
315         sdata->len = sdblob.length;
316
317         if (sec_info_ptr) {
318                 sec_info = *sec_info_ptr;
319         } else {
320                 sec_info = SECINFO_UNPROTECTED_SACL |
321                            SECINFO_UNPROTECTED_DACL;
322                 if (sd->owner_sid) {
323                         sec_info |= SECINFO_OWNER;
324                 }
325                 if (sd->group_sid) {
326                         sec_info |= SECINFO_GROUP;
327                 }
328                 if (sd->sacl) {
329                         sec_info |= SECINFO_SACL;
330                 }
331                 if (sd->dacl) {
332                         sec_info |= SECINFO_DACL;
333                 }
334         }
335
336         r.in.handle = handle;
337         r.in.sec_info = sec_info;
338         r.in.sd = sdata;
339
340         torture_assert_ntstatus_ok(tctx,
341                                    dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
342                                    "SetKeySecurity failed");
343
344         torture_assert_werr_equal(tctx, r.out.result, werr,
345                                   "SetKeySecurity failed");
346
347         return true;
348 }
349
350 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
351                                 struct torture_context *tctx,
352                                 struct policy_handle *handle,
353                                 struct security_descriptor *sd)
354 {
355         return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
356 }
357
358 static bool test_CloseKey(struct dcerpc_binding_handle *b,
359                           struct torture_context *tctx,
360                           struct policy_handle *handle)
361 {
362         struct winreg_CloseKey r;
363
364         ZERO_STRUCT(r);
365         r.in.handle = r.out.handle = handle;
366
367         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
368                                    "CloseKey failed");
369
370         torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
371
372         return true;
373 }
374
375 static bool test_FlushKey(struct dcerpc_binding_handle *b,
376                           struct torture_context *tctx,
377                           struct policy_handle *handle)
378 {
379         struct winreg_FlushKey r;
380
381         ZERO_STRUCT(r);
382         r.in.handle = handle;
383
384         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
385                                    "FlushKey failed");
386
387         torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
388
389         return true;
390 }
391
392 static bool test_OpenKey_opts(struct torture_context *tctx,
393                               struct dcerpc_binding_handle *b,
394                               struct policy_handle *hive_handle,
395                               const char *keyname,
396                               uint32_t options,
397                               uint32_t access_mask,
398                               struct policy_handle *key_handle,
399                               WERROR expected_result)
400 {
401         struct winreg_OpenKey r;
402
403         ZERO_STRUCT(r);
404         r.in.parent_handle = hive_handle;
405         init_winreg_String(&r.in.keyname, keyname);
406         r.in.options = options;
407         r.in.access_mask = access_mask;
408         r.out.handle = key_handle;
409
410         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
411                                    "OpenKey failed");
412
413         torture_assert_werr_equal(tctx, r.out.result, expected_result,
414                                   "OpenKey failed");
415
416         return true;
417 }
418
419 static bool test_OpenKey(struct dcerpc_binding_handle *b,
420                          struct torture_context *tctx,
421                          struct policy_handle *hive_handle,
422                          const char *keyname, struct policy_handle *key_handle)
423 {
424         return test_OpenKey_opts(tctx, b, hive_handle, keyname,
425                                  REG_OPTION_NON_VOLATILE,
426                                  SEC_FLAG_MAXIMUM_ALLOWED,
427                                  key_handle,
428                                  WERR_OK);
429 }
430
431 static bool test_Cleanup(struct dcerpc_binding_handle *b,
432                          struct torture_context *tctx,
433                          struct policy_handle *handle, const char *key)
434 {
435         struct winreg_DeleteKey r;
436
437         ZERO_STRUCT(r);
438         r.in.handle = handle;
439
440         init_winreg_String(&r.in.key, key);
441         dcerpc_winreg_DeleteKey_r(b, tctx, &r);
442
443         return true;
444 }
445
446 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
447                                            struct torture_context *tctx,
448                                            struct policy_handle *handle,
449                                            WERROR get_werr,
450                                            WERROR set_werr)
451 {
452         struct security_descriptor *sd = NULL;
453
454         if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
455                 return false;
456         }
457
458         if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
459                 return false;
460         }
461
462         return true;
463 }
464
465 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
466                                     struct torture_context *tctx,
467                                     struct policy_handle *handle,
468                                     const char *key)
469 {
470         struct policy_handle new_handle;
471         bool ret = true;
472         struct dcerpc_binding_handle *b = p->binding_handle;
473
474         torture_comment(tctx, "SecurityDescriptor get & set\n");
475
476         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
477                 return false;
478         }
479
480         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
481                                             WERR_OK, WERR_OK)) {
482                 ret = false;
483         }
484
485         if (!test_CloseKey(b, tctx, &new_handle)) {
486                 return false;
487         }
488
489         return ret;
490 }
491
492 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
493                                      struct torture_context *tctx,
494                                      struct policy_handle *handle,
495                                      uint32_t access_mask,
496                                      const char *key,
497                                      WERROR open_werr,
498                                      WERROR get_werr,
499                                      WERROR set_werr)
500 {
501         struct policy_handle new_handle;
502         bool ret = true;
503         struct dcerpc_binding_handle *b = p->binding_handle;
504
505         torture_assert(tctx,
506                 test_OpenKey_opts(tctx, b, handle, key,
507                                   REG_OPTION_NON_VOLATILE,
508                                   access_mask,
509                                   &new_handle,
510                                   open_werr),
511                 "failed to open key");
512
513         if (!W_ERROR_IS_OK(open_werr)) {
514                 return true;
515         }
516
517         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
518                                             get_werr, set_werr)) {
519                 ret = false;
520         }
521
522         if (!test_CloseKey(b, tctx, &new_handle)) {
523                 return false;
524         }
525
526         return ret;
527 }
528
529 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
530                                       struct torture_context *tctx,
531                                       struct policy_handle *handle,
532                                       const struct dom_sid *sid)
533 {
534         struct security_descriptor *sd = NULL;
535         int i;
536
537         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
538                 return false;
539         }
540
541         if (!sd || !sd->dacl) {
542                 return false;
543         }
544
545         for (i = 0; i < sd->dacl->num_aces; i++) {
546                 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
547                         return true;
548                 }
549         }
550
551         return false;
552 }
553
554 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
555                                        struct torture_context *tctx,
556                                        struct policy_handle *handle,
557                                        const char *key,
558                                        const struct dom_sid *sid)
559 {
560         struct policy_handle new_handle;
561         bool ret = true;
562         struct dcerpc_binding_handle *b = p->binding_handle;
563
564         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
565                 return false;
566         }
567
568         ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
569
570         test_CloseKey(b, tctx, &new_handle);
571
572         return ret;
573 }
574
575 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
576                                       struct torture_context *tctx,
577                                       struct policy_handle *handle,
578                                       const struct dom_sid *sid)
579 {
580         struct security_descriptor *sd = NULL;
581         int i;
582         uint32_t sec_info = SECINFO_SACL;
583
584         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
585                 return false;
586         }
587
588         if (!sd || !sd->sacl) {
589                 return false;
590         }
591
592         for (i = 0; i < sd->sacl->num_aces; i++) {
593                 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
594                         return true;
595                 }
596         }
597
598         return false;
599 }
600
601 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
602                                        struct torture_context *tctx,
603                                        struct policy_handle *handle,
604                                        const char *key,
605                                        const struct dom_sid *sid)
606 {
607         struct policy_handle new_handle;
608         bool ret = true;
609         struct dcerpc_binding_handle *b = p->binding_handle;
610
611         torture_assert(tctx,
612                 test_OpenKey_opts(tctx, b, handle, key,
613                                   REG_OPTION_NON_VOLATILE,
614                                   SEC_FLAG_SYSTEM_SECURITY,
615                                   &new_handle,
616                                   WERR_OK),
617                 "failed to open key");
618
619         ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
620
621         test_CloseKey(b, tctx, &new_handle);
622
623         return ret;
624 }
625
626 static bool test_owner_present(struct dcerpc_pipe *p,
627                                struct torture_context *tctx,
628                                struct policy_handle *handle,
629                                const struct dom_sid *sid)
630 {
631         struct security_descriptor *sd = NULL;
632         uint32_t sec_info = SECINFO_OWNER;
633
634         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
635                 return false;
636         }
637
638         if (!sd || !sd->owner_sid) {
639                 return false;
640         }
641
642         return dom_sid_equal(sd->owner_sid, sid);
643 }
644
645 static bool _test_owner_present(struct dcerpc_pipe *p,
646                                 struct torture_context *tctx,
647                                 struct policy_handle *handle,
648                                 const char *key,
649                                 const struct dom_sid *sid)
650 {
651         struct policy_handle new_handle;
652         bool ret = true;
653         struct dcerpc_binding_handle *b = p->binding_handle;
654
655         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
656                 return false;
657         }
658
659         ret = test_owner_present(p, tctx, &new_handle, sid);
660
661         test_CloseKey(b, tctx, &new_handle);
662
663         return ret;
664 }
665
666 static bool test_group_present(struct dcerpc_pipe *p,
667                                struct torture_context *tctx,
668                                struct policy_handle *handle,
669                                const struct dom_sid *sid)
670 {
671         struct security_descriptor *sd = NULL;
672         uint32_t sec_info = SECINFO_GROUP;
673
674         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
675                 return false;
676         }
677
678         if (!sd || !sd->group_sid) {
679                 return false;
680         }
681
682         return dom_sid_equal(sd->group_sid, sid);
683 }
684
685 static bool _test_group_present(struct dcerpc_pipe *p,
686                                 struct torture_context *tctx,
687                                 struct policy_handle *handle,
688                                 const char *key,
689                                 const struct dom_sid *sid)
690 {
691         struct policy_handle new_handle;
692         bool ret = true;
693         struct dcerpc_binding_handle *b = p->binding_handle;
694
695         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
696                 return false;
697         }
698
699         ret = test_group_present(p, tctx, &new_handle, sid);
700
701         test_CloseKey(b, tctx, &new_handle);
702
703         return ret;
704 }
705
706 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
707                                             struct torture_context *tctx,
708                                             struct policy_handle *handle,
709                                             const struct dom_sid *sid,
710                                             uint8_t flags)
711 {
712         struct security_descriptor *sd = NULL;
713         int i;
714
715         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
716                 return false;
717         }
718
719         if (!sd || !sd->dacl) {
720                 return false;
721         }
722
723         for (i = 0; i < sd->dacl->num_aces; i++) {
724                 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
725                     (sd->dacl->aces[i].flags == flags)) {
726                         return true;
727                 }
728         }
729
730         return false;
731 }
732
733 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
734                                   struct torture_context *tctx,
735                                   struct policy_handle *handle,
736                                   const struct security_ace *ace)
737 {
738         struct security_descriptor *sd = NULL;
739         int i;
740
741         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
742                 return false;
743         }
744
745         if (!sd || !sd->dacl) {
746                 return false;
747         }
748
749         for (i = 0; i < sd->dacl->num_aces; i++) {
750                 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
751                         return true;
752                 }
753         }
754
755         return false;
756 }
757
758 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
759                                  struct torture_context *tctx,
760                                  struct policy_handle *handle,
761                                  const char *key,
762                                  struct security_descriptor *sd)
763 {
764         struct policy_handle new_handle;
765         bool ret = true;
766         struct dcerpc_binding_handle *b = p->binding_handle;
767
768         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
769                 return false;
770         }
771
772         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
773                 ret = false;
774         }
775
776         if (!test_CloseKey(b, tctx, &new_handle)) {
777                 ret = false;
778         }
779
780         return ret;
781 }
782
783 static bool test_BackupSecurity(struct dcerpc_pipe *p,
784                                 struct torture_context *tctx,
785                                 struct policy_handle *handle,
786                                 const char *key,
787                                 struct security_descriptor **sd)
788 {
789         struct policy_handle new_handle;
790         bool ret = true;
791         struct dcerpc_binding_handle *b = p->binding_handle;
792
793         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
794                 return false;
795         }
796
797         if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
798                 ret = false;
799         }
800
801         if (!test_CloseKey(b, tctx, &new_handle)) {
802                 ret = false;
803         }
804
805         return ret;
806 }
807
808 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
809                                                struct torture_context *tctx,
810                                                struct policy_handle *handle,
811                                                const char *key)
812 {
813         /* get sd
814            add ace SEC_ACE_FLAG_CONTAINER_INHERIT
815            set sd
816            get sd
817            check ace
818            add subkey
819            get sd
820            check ace
821            add subsubkey
822            get sd
823            check ace
824            del subsubkey
825            del subkey
826            reset sd
827         */
828
829         struct security_descriptor *sd = NULL;
830         struct security_descriptor *sd_orig = NULL;
831         struct security_ace *ace = NULL;
832         struct policy_handle new_handle;
833         bool ret = true;
834         struct dcerpc_binding_handle *b = p->binding_handle;
835
836         torture_comment(tctx, "SecurityDescriptor inheritance\n");
837
838         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
839                 return false;
840         }
841
842         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
843                 return false;
844         }
845
846         sd_orig = security_descriptor_copy(tctx, sd);
847         if (sd_orig == NULL) {
848                 return false;
849         }
850
851         ace = security_ace_create(tctx,
852                                   TEST_SID,
853                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
854                                   SEC_STD_REQUIRED,
855                                   SEC_ACE_FLAG_CONTAINER_INHERIT);
856
857         torture_assert_ntstatus_ok(tctx,
858                 security_descriptor_dacl_add(sd, ace),
859                 "failed to add ace");
860
861         /* FIXME: add further tests for these flags */
862         sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
863                     SEC_DESC_SACL_AUTO_INHERITED;
864
865         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
866                 return false;
867         }
868
869         torture_assert(tctx,
870                 test_dacl_ace_present(p, tctx, &new_handle, ace),
871                 "new ACE not present!");
872
873         if (!test_CloseKey(b, tctx, &new_handle)) {
874                 return false;
875         }
876
877         if (!test_CreateKey(b, tctx, handle, TEST_SUBKEY_SD, NULL)) {
878                 ret = false;
879                 goto out;
880         }
881
882         if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
883                 ret = false;
884                 goto out;
885         }
886
887         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
888                 torture_comment(tctx, "inherited ACE not present!\n");
889                 ret = false;
890                 goto out;
891         }
892
893         test_CloseKey(b, tctx, &new_handle);
894         if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
895                 ret = false;
896                 goto out;
897         }
898
899         if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
900                 ret = false;
901                 goto out;
902         }
903
904         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
905                 torture_comment(tctx, "inherited ACE not present!\n");
906                 ret = false;
907                 goto out;
908         }
909
910  out:
911         test_CloseKey(b, tctx, &new_handle);
912         test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
913         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
914
915         return true;
916 }
917
918 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
919                                                     struct torture_context *tctx,
920                                                     struct policy_handle *handle,
921                                                     const char *key)
922 {
923         /* get sd
924            add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
925            set sd
926            add subkey/subkey
927            get sd
928            check ace
929            get sd from subkey
930            check ace
931            del subkey/subkey
932            del subkey
933            reset sd
934         */
935
936         struct security_descriptor *sd = NULL;
937         struct security_descriptor *sd_orig = NULL;
938         struct security_ace *ace = NULL;
939         struct policy_handle new_handle;
940         struct dom_sid *sid = NULL;
941         bool ret = true;
942         uint8_t ace_flags = 0x0;
943         struct dcerpc_binding_handle *b = p->binding_handle;
944
945         torture_comment(tctx, "SecurityDescriptor inheritance block\n");
946
947         if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
948                 return false;
949         }
950
951         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
952                 return false;
953         }
954
955         sd_orig = security_descriptor_copy(tctx, sd);
956         if (sd_orig == NULL) {
957                 return false;
958         }
959
960         ace = security_ace_create(tctx,
961                                   TEST_SID,
962                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
963                                   SEC_STD_REQUIRED,
964                                   SEC_ACE_FLAG_CONTAINER_INHERIT |
965                                   SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
966
967         torture_assert_ntstatus_ok(tctx,
968                 security_descriptor_dacl_add(sd, ace),
969                 "failed to add ace");
970
971         if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
972                 return false;
973         }
974
975         torture_assert(tctx,
976                 test_dacl_ace_present(p, tctx, &new_handle, ace),
977                 "new ACE not present!");
978
979         if (!test_CloseKey(b, tctx, &new_handle)) {
980                 return false;
981         }
982
983         if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
984                 return false;
985         }
986
987         if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
988                 ret = false;
989                 goto out;
990         }
991
992         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
993                 torture_comment(tctx, "inherited ACE present but should not!\n");
994                 ret = false;
995                 goto out;
996         }
997
998         sid = dom_sid_parse_talloc(tctx, TEST_SID);
999         if (sid == NULL) {
1000                 return false;
1001         }
1002
1003         if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1004                 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1005                 ret = false;
1006                 goto out;
1007         }
1008
1009         test_CloseKey(b, tctx, &new_handle);
1010
1011         if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
1012                 ret = false;
1013                 goto out;
1014         }
1015
1016         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1017                 torture_comment(tctx, "inherited ACE present but should not!\n");
1018                 ret = false;
1019                 goto out;
1020         }
1021
1022         if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1023                 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1024                         ace_flags);
1025                 ret = false;
1026                 goto out;
1027         }
1028
1029  out:
1030         test_CloseKey(b, tctx, &new_handle);
1031         test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
1032         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1033
1034         return ret;
1035 }
1036
1037 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1038                                           struct torture_context *tctx,
1039                                           struct policy_handle *handle,
1040                                           const char *key)
1041 {
1042         bool ret = true;
1043         int i;
1044
1045         struct winreg_mask_result_table {
1046                 uint32_t access_mask;
1047                 WERROR open_werr;
1048                 WERROR get_werr;
1049                 WERROR set_werr;
1050         } sd_mask_tests[] = {
1051                 { 0,
1052                         WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1053                 { SEC_FLAG_MAXIMUM_ALLOWED,
1054                         WERR_OK, WERR_OK, WERR_OK },
1055                 { SEC_STD_WRITE_DAC,
1056                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1057                 { SEC_FLAG_SYSTEM_SECURITY,
1058                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1059         };
1060
1061         /* FIXME: before this test can ever run successfully we need a way to
1062          * correctly read a NULL security_descritpor in ndr, get the required
1063          * length, requery, etc.
1064          */
1065
1066         return true;
1067
1068         for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1069
1070                 torture_comment(tctx,
1071                                 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1072                                 sd_mask_tests[i].access_mask);
1073                 torture_comment(tctx,
1074                                 "expecting: open %s, get: %s, set: %s\n",
1075                                 win_errstr(sd_mask_tests[i].open_werr),
1076                                 win_errstr(sd_mask_tests[i].get_werr),
1077                                 win_errstr(sd_mask_tests[i].set_werr));
1078
1079                 if (_test_SecurityDescriptor(p, tctx, handle,
1080                                              sd_mask_tests[i].access_mask, key,
1081                                              sd_mask_tests[i].open_werr,
1082                                              sd_mask_tests[i].get_werr,
1083                                              sd_mask_tests[i].set_werr)) {
1084                         ret = false;
1085                 }
1086         }
1087
1088         return ret;
1089 }
1090
1091 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1092                                   struct torture_context *,
1093                                   struct policy_handle *,
1094                                   const char *,
1095                                   const struct dom_sid *);
1096
1097 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1098                                                struct torture_context *tctx,
1099                                                struct policy_handle *handle,
1100                                                const char *key,
1101                                                const char *test,
1102                                                uint32_t access_mask,
1103                                                uint32_t sec_info,
1104                                                struct security_descriptor *sd,
1105                                                WERROR set_werr,
1106                                                bool expect_present,
1107                                                bool (*fn) (struct dcerpc_pipe *,
1108                                                            struct torture_context *,
1109                                                            struct policy_handle *,
1110                                                            const char *,
1111                                                            const struct dom_sid *),
1112                                                const struct dom_sid *sid)
1113 {
1114         struct policy_handle new_handle;
1115         struct dcerpc_binding_handle *b = p->binding_handle;
1116
1117         torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1118                         "0x%08x, access_mask: 0x%08x\n",
1119                         test, sec_info, access_mask);
1120
1121         torture_assert(tctx,
1122                 test_OpenKey_opts(tctx, b, handle, key,
1123                                   REG_OPTION_NON_VOLATILE,
1124                                   access_mask,
1125                                   &new_handle,
1126                                   WERR_OK),
1127                 "failed to open key");
1128
1129         if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1130                                   sd,
1131                                   set_werr)) {
1132                 torture_warning(tctx,
1133                                 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1134                                 sec_info);
1135                 smb_panic("");
1136                 test_CloseKey(b, tctx, &new_handle);
1137                 return false;
1138         }
1139
1140         test_CloseKey(b, tctx, &new_handle);
1141
1142         if (W_ERROR_IS_OK(set_werr)) {
1143                 bool present;
1144                 present = fn(p, tctx, handle, key, sid);
1145                 if ((expect_present) && (!present)) {
1146                         torture_warning(tctx,
1147                                         "%s sid is not present!\n",
1148                                         test);
1149                         return false;
1150                 }
1151                 if ((!expect_present) && (present)) {
1152                         torture_warning(tctx,
1153                                         "%s sid is present but not expected!\n",
1154                                         test);
1155                         return false;
1156                 }
1157         }
1158
1159         return true;
1160 }
1161
1162 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1163                                             struct torture_context *tctx,
1164                                             struct policy_handle *handle,
1165                                             const char *key)
1166 {
1167         struct security_descriptor *sd_orig = NULL;
1168         struct dom_sid *sid = NULL;
1169         bool ret = true;
1170         int i, a;
1171
1172         struct security_descriptor *sd_owner =
1173                 security_descriptor_dacl_create(tctx,
1174                                                 0,
1175                                                 TEST_SID, NULL, NULL);
1176
1177         struct security_descriptor *sd_group =
1178                 security_descriptor_dacl_create(tctx,
1179                                                 0,
1180                                                 NULL, TEST_SID, NULL);
1181
1182         struct security_descriptor *sd_dacl =
1183                 security_descriptor_dacl_create(tctx,
1184                                                 0,
1185                                                 NULL, NULL,
1186                                                 TEST_SID,
1187                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1188                                                 SEC_GENERIC_ALL,
1189                                                 0,
1190                                                 SID_NT_AUTHENTICATED_USERS,
1191                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1192                                                 SEC_GENERIC_ALL,
1193                                                 0,
1194                                                 NULL);
1195
1196         struct security_descriptor *sd_sacl =
1197                 security_descriptor_sacl_create(tctx,
1198                                                 0,
1199                                                 NULL, NULL,
1200                                                 TEST_SID,
1201                                                 SEC_ACE_TYPE_SYSTEM_AUDIT,
1202                                                 SEC_GENERIC_ALL,
1203                                                 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1204                                                 NULL);
1205
1206         struct winreg_secinfo_table {
1207                 struct security_descriptor *sd;
1208                 uint32_t sec_info;
1209                 WERROR set_werr;
1210                 bool sid_present;
1211                 secinfo_verify_fn fn;
1212         };
1213
1214         struct winreg_secinfo_table sec_info_owner_tests[] = {
1215                 { sd_owner, 0, WERR_OK,
1216                         false, (secinfo_verify_fn)_test_owner_present },
1217                 { sd_owner, SECINFO_OWNER, WERR_OK,
1218                         true, (secinfo_verify_fn)_test_owner_present },
1219                 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1220                 { sd_owner, SECINFO_DACL, WERR_OK,
1221                         true, (secinfo_verify_fn)_test_owner_present },
1222                 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1223         };
1224
1225         uint32_t sd_owner_good_access_masks[] = {
1226                 SEC_FLAG_MAXIMUM_ALLOWED,
1227                 /* SEC_STD_WRITE_OWNER, */
1228         };
1229
1230         struct winreg_secinfo_table sec_info_group_tests[] = {
1231                 { sd_group, 0, WERR_OK,
1232                         false, (secinfo_verify_fn)_test_group_present },
1233                 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1234                 { sd_group, SECINFO_GROUP, WERR_OK,
1235                         true, (secinfo_verify_fn)_test_group_present },
1236                 { sd_group, SECINFO_DACL, WERR_OK,
1237                         true, (secinfo_verify_fn)_test_group_present },
1238                 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1239         };
1240
1241         uint32_t sd_group_good_access_masks[] = {
1242                 SEC_FLAG_MAXIMUM_ALLOWED,
1243         };
1244
1245         struct winreg_secinfo_table sec_info_dacl_tests[] = {
1246                 { sd_dacl, 0, WERR_OK,
1247                         false, (secinfo_verify_fn)_test_dacl_trustee_present },
1248                 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1249                 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1250                 { sd_dacl, SECINFO_DACL, WERR_OK,
1251                         true, (secinfo_verify_fn)_test_dacl_trustee_present },
1252                 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1253         };
1254
1255         uint32_t sd_dacl_good_access_masks[] = {
1256                 SEC_FLAG_MAXIMUM_ALLOWED,
1257                 SEC_STD_WRITE_DAC,
1258         };
1259
1260         struct winreg_secinfo_table sec_info_sacl_tests[] = {
1261                 { sd_sacl, 0, WERR_OK,
1262                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1263                 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1264                 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1265                 { sd_sacl, SECINFO_DACL, WERR_OK,
1266                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1267                 { sd_sacl, SECINFO_SACL, WERR_OK,
1268                         true, (secinfo_verify_fn)_test_sacl_trustee_present },
1269         };
1270
1271         uint32_t sd_sacl_good_access_masks[] = {
1272                 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1273                 /* SEC_FLAG_SYSTEM_SECURITY, */
1274         };
1275
1276         sid = dom_sid_parse_talloc(tctx, TEST_SID);
1277         if (sid == NULL) {
1278                 return false;
1279         }
1280
1281         if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1282                 return false;
1283         }
1284
1285         /* OWNER */
1286
1287         for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1288
1289                 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1290
1291                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1292                                         key,
1293                                         "OWNER",
1294                                         sd_owner_good_access_masks[a],
1295                                         sec_info_owner_tests[i].sec_info,
1296                                         sec_info_owner_tests[i].sd,
1297                                         sec_info_owner_tests[i].set_werr,
1298                                         sec_info_owner_tests[i].sid_present,
1299                                         sec_info_owner_tests[i].fn,
1300                                         sid))
1301                         {
1302                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1303                                 ret = false;
1304                                 goto out;
1305                         }
1306                 }
1307         }
1308
1309         /* GROUP */
1310
1311         for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1312
1313                 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1314
1315                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1316                                         key,
1317                                         "GROUP",
1318                                         sd_group_good_access_masks[a],
1319                                         sec_info_group_tests[i].sec_info,
1320                                         sec_info_group_tests[i].sd,
1321                                         sec_info_group_tests[i].set_werr,
1322                                         sec_info_group_tests[i].sid_present,
1323                                         sec_info_group_tests[i].fn,
1324                                         sid))
1325                         {
1326                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1327                                 ret = false;
1328                                 goto out;
1329                         }
1330                 }
1331         }
1332
1333         /* DACL */
1334
1335         for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1336
1337                 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1338
1339                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1340                                         key,
1341                                         "DACL",
1342                                         sd_dacl_good_access_masks[a],
1343                                         sec_info_dacl_tests[i].sec_info,
1344                                         sec_info_dacl_tests[i].sd,
1345                                         sec_info_dacl_tests[i].set_werr,
1346                                         sec_info_dacl_tests[i].sid_present,
1347                                         sec_info_dacl_tests[i].fn,
1348                                         sid))
1349                         {
1350                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1351                                 ret = false;
1352                                 goto out;
1353                         }
1354                 }
1355         }
1356
1357         /* SACL */
1358
1359         for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1360
1361                 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1362
1363                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1364                                         key,
1365                                         "SACL",
1366                                         sd_sacl_good_access_masks[a],
1367                                         sec_info_sacl_tests[i].sec_info,
1368                                         sec_info_sacl_tests[i].sd,
1369                                         sec_info_sacl_tests[i].set_werr,
1370                                         sec_info_sacl_tests[i].sid_present,
1371                                         sec_info_sacl_tests[i].fn,
1372                                         sid))
1373                         {
1374                                 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1375                                 ret = false;
1376                                 goto out;
1377                         }
1378                 }
1379         }
1380
1381  out:
1382         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1383
1384         return ret;
1385 }
1386
1387 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1388                                      struct torture_context *tctx,
1389                                      struct policy_handle *handle,
1390                                      const char *key)
1391 {
1392         bool ret = true;
1393
1394         if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1395                 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1396                 ret = false;
1397         }
1398
1399         if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1400                 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1401                 ret = false;
1402         }
1403
1404         if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1405                 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1406                 ret = false;
1407         }
1408
1409         if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1410                 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1411                 ret = false;
1412         }
1413
1414         if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1415                 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1416                 ret = false;
1417         }
1418
1419         return ret;
1420 }
1421
1422 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1423                                 struct torture_context *tctx,
1424                                 struct policy_handle *handle,
1425                                 const char *key,
1426                                 WERROR expected_result)
1427 {
1428         struct winreg_DeleteKey r;
1429
1430         torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1431
1432         r.in.handle = handle;
1433         init_winreg_String(&r.in.key, key);
1434
1435         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1436                 "Delete Key failed");
1437         torture_assert_werr_equal(tctx, r.out.result, expected_result,
1438                 "DeleteKey failed");
1439
1440         return true;
1441 }
1442
1443 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1444                            struct torture_context *tctx,
1445                            struct policy_handle *handle, const char *key)
1446 {
1447         return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1448 }
1449
1450 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1451                               struct torture_context *tctx,
1452                               struct policy_handle *handle, char *kclass)
1453 {
1454         struct winreg_QueryInfoKey r;
1455         uint32_t num_subkeys, max_subkeylen, max_classlen,
1456                 num_values, max_valnamelen, max_valbufsize,
1457                 secdescsize;
1458         NTTIME last_changed_time;
1459
1460         ZERO_STRUCT(r);
1461         r.in.handle = handle;
1462         r.out.num_subkeys = &num_subkeys;
1463         r.out.max_subkeylen = &max_subkeylen;
1464         r.out.max_classlen = &max_classlen;
1465         r.out.num_values = &num_values;
1466         r.out.max_valnamelen = &max_valnamelen;
1467         r.out.max_valbufsize = &max_valbufsize;
1468         r.out.secdescsize = &secdescsize;
1469         r.out.last_changed_time = &last_changed_time;
1470
1471         r.out.classname = talloc(tctx, struct winreg_String);
1472
1473         r.in.classname = talloc(tctx, struct winreg_String);
1474         init_winreg_String(r.in.classname, kclass);
1475
1476         torture_assert_ntstatus_ok(tctx,
1477                                    dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1478                                    "QueryInfoKey failed");
1479
1480         torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1481
1482         return true;
1483 }
1484
1485 static bool test_SetValue(struct dcerpc_binding_handle *b,
1486                           struct torture_context *tctx,
1487                           struct policy_handle *handle,
1488                           const char *value_name,
1489                           enum winreg_Type type,
1490                           uint8_t *data,
1491                           uint32_t size)
1492 {
1493         struct winreg_SetValue r;
1494         struct winreg_String name;
1495
1496         torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1497                 value_name, str_regtype(type), size);
1498
1499         init_winreg_String(&name, value_name);
1500
1501         r.in.handle = handle;
1502         r.in.name = name;
1503         r.in.type = type;
1504         r.in.data = data;
1505         r.in.size = size;
1506
1507         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1508                 "winreg_SetValue failed");
1509         torture_assert_werr_ok(tctx, r.out.result,
1510                 "winreg_SetValue failed");
1511
1512         return true;
1513 }
1514
1515 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1516                              struct torture_context *tctx,
1517                              struct policy_handle *handle,
1518                              const char *value_name)
1519 {
1520         struct winreg_DeleteValue r;
1521         struct winreg_String value;
1522
1523         torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1524
1525         init_winreg_String(&value, value_name);
1526
1527         r.in.handle = handle;
1528         r.in.value = value;
1529
1530         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1531                 "winreg_DeleteValue failed");
1532         torture_assert_werr_ok(tctx, r.out.result,
1533                 "winreg_DeleteValue failed");
1534
1535         return true;
1536 }
1537
1538 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1539                      struct policy_handle *handle, int depth,
1540                      bool test_security);
1541
1542 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1543                          struct policy_handle *handle, int depth,
1544                          bool test_security)
1545 {
1546         struct winreg_EnumKey r;
1547         struct winreg_StringBuf kclass, name;
1548         NTSTATUS status;
1549         NTTIME t = 0;
1550         struct dcerpc_binding_handle *b = p->binding_handle;
1551
1552         kclass.name   = "";
1553         kclass.size   = 1024;
1554
1555         ZERO_STRUCT(r);
1556         r.in.handle = handle;
1557         r.in.enum_index = 0;
1558         r.in.name = &name;
1559         r.in.keyclass = &kclass;
1560         r.out.name = &name;
1561         r.in.last_changed_time = &t;
1562
1563         do {
1564                 name.name   = NULL;
1565                 name.size   = 1024;
1566
1567                 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1568
1569                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1570                         struct policy_handle key_handle;
1571
1572                         torture_comment(tctx, "EnumKey: %d: %s\n",
1573                                         r.in.enum_index,
1574                                         r.out.name->name);
1575
1576                         if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1577                                           &key_handle)) {
1578                         } else {
1579                                 test_key(p, tctx, &key_handle,
1580                                          depth + 1, test_security);
1581                         }
1582                 }
1583
1584                 r.in.enum_index++;
1585
1586         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1587
1588         torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1589
1590         if (!W_ERROR_IS_OK(r.out.result) &&
1591                 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1592                 torture_fail(tctx, "EnumKey failed");
1593         }
1594
1595         return true;
1596 }
1597
1598 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1599                                      struct torture_context *tctx,
1600                                      struct policy_handle *handle,
1601                                      const char *valuename)
1602 {
1603         struct winreg_QueryMultipleValues r;
1604         uint32_t bufsize=0;
1605
1606         ZERO_STRUCT(r);
1607         r.in.key_handle = handle;
1608         r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1609         r.in.values[0].name = talloc(tctx, struct winreg_String);
1610         r.in.values[0].name->name = valuename;
1611         r.in.values[0].offset = 0;
1612         r.in.values[0].length = 0;
1613         r.in.values[0].type = 0;
1614
1615         r.in.num_values = 1;
1616         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1617         *r.in.buffer_size = bufsize;
1618         do {
1619                 *r.in.buffer_size = bufsize;
1620                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1621                                                                *r.in.buffer_size);
1622
1623                 torture_assert_ntstatus_ok(tctx,
1624                         dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1625                         "QueryMultipleValues failed");
1626
1627                 talloc_free(r.in.buffer);
1628                 bufsize += 0x20;
1629         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1630
1631         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1632
1633         return true;
1634 }
1635
1636 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1637                             struct torture_context *tctx,
1638                             struct policy_handle *handle,
1639                             const char *valuename)
1640 {
1641         struct winreg_QueryValue r;
1642         NTSTATUS status;
1643         enum winreg_Type zero_type = 0;
1644         uint32_t offered = 0xfff;
1645         uint32_t zero = 0;
1646
1647         ZERO_STRUCT(r);
1648         r.in.handle = handle;
1649         r.in.data = NULL;
1650         r.in.value_name = talloc_zero(tctx, struct winreg_String);
1651         r.in.value_name->name = valuename;
1652         r.in.type = &zero_type;
1653         r.in.data_size = &offered;
1654         r.in.data_length = &zero;
1655
1656         status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1657         if (NT_STATUS_IS_ERR(status)) {
1658                 torture_fail(tctx, "QueryValue failed");
1659         }
1660
1661         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1662
1663         return true;
1664 }
1665
1666 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1667                                  struct torture_context *tctx,
1668                                  struct policy_handle *handle,
1669                                  const char *valuename,
1670                                  bool existing_value)
1671 {
1672         struct winreg_QueryValue r;
1673         struct winreg_String value_name;
1674         enum winreg_Type type = REG_NONE;
1675         uint32_t data_size = 0;
1676         uint32_t real_data_size = 0;
1677         uint32_t data_length = 0;
1678         uint8_t *data = NULL;
1679         WERROR expected_error = WERR_BADFILE;
1680
1681         if (valuename == NULL) {
1682                 expected_error = WERR_INVALID_PARAM;
1683         }
1684
1685         ZERO_STRUCT(r);
1686
1687         init_winreg_String(&value_name, NULL);
1688
1689         torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1690
1691         r.in.handle = handle;
1692         r.in.value_name = &value_name;
1693
1694         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1695         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1696                 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1697
1698         init_winreg_String(&value_name, valuename);
1699         r.in.value_name = &value_name;
1700
1701         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1702                 "QueryValue failed");
1703         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1704                 "QueryValue failed");
1705
1706         r.in.type = &type;
1707         r.out.type = &type;
1708         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1709                 "QueryValue failed");
1710         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1711                 "QueryValue failed");
1712
1713         r.in.data_length = &data_length;
1714         r.out.data_length = &data_length;
1715         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1716                 "QueryValue failed");
1717         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1718                 "QueryValue failed");
1719
1720         r.in.data_size = &data_size;
1721         r.out.data_size = &data_size;
1722         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1723                 "QueryValue failed");
1724         if (existing_value) {
1725                 torture_assert_werr_ok(tctx, r.out.result,
1726                         "QueryValue failed");
1727         } else {
1728                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1729                         "QueryValue failed");
1730         }
1731
1732         real_data_size = *r.out.data_size;
1733
1734         data = talloc_zero_array(tctx, uint8_t, 0);
1735         r.in.data = data;
1736         r.out.data = data;
1737         *r.in.data_size = 0;
1738         *r.out.data_size = 0;
1739         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1740                 "QueryValue failed");
1741         if (existing_value) {
1742                 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1743                         "QueryValue failed");
1744         } else {
1745                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1746                         "QueryValue failed");
1747         }
1748
1749         data = talloc_zero_array(tctx, uint8_t, real_data_size);
1750         r.in.data = data;
1751         r.out.data = data;
1752         r.in.data_size = &real_data_size;
1753         r.out.data_size = &real_data_size;
1754         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1755                 "QueryValue failed");
1756         if (existing_value) {
1757                 torture_assert_werr_ok(tctx, r.out.result,
1758                         "QueryValue failed");
1759         } else {
1760                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1761                         "QueryValue failed");
1762         }
1763
1764         return true;
1765 }
1766
1767 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1768                            struct torture_context *tctx,
1769                            struct policy_handle *handle, int max_valnamelen,
1770                            int max_valbufsize)
1771 {
1772         struct winreg_EnumValue r;
1773         enum winreg_Type type = 0;
1774         uint32_t size = max_valbufsize, zero = 0;
1775         bool ret = true;
1776         uint8_t buf8;
1777         struct winreg_ValNameBuf name;
1778
1779         name.name   = "";
1780         name.size   = 1024;
1781
1782         ZERO_STRUCT(r);
1783         r.in.handle = handle;
1784         r.in.enum_index = 0;
1785         r.in.name = &name;
1786         r.out.name = &name;
1787         r.in.type = &type;
1788         r.in.value = &buf8;
1789         r.in.length = &zero;
1790         r.in.size = &size;
1791
1792         do {
1793                 torture_assert_ntstatus_ok(tctx,
1794                                            dcerpc_winreg_EnumValue_r(b, tctx, &r),
1795                                            "EnumValue failed");
1796
1797                 if (W_ERROR_IS_OK(r.out.result)) {
1798                         ret &= test_QueryValue(b, tctx, handle,
1799                                                r.out.name->name);
1800                         ret &= test_QueryMultipleValues(b, tctx, handle,
1801                                                         r.out.name->name);
1802                 }
1803
1804                 r.in.enum_index++;
1805         } while (W_ERROR_IS_OK(r.out.result));
1806
1807         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1808                                   "EnumValue failed");
1809
1810         return ret;
1811 }
1812
1813 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
1814                                      struct torture_context *tctx)
1815 {
1816         struct winreg_AbortSystemShutdown r;
1817         uint16_t server = 0x0;
1818
1819         ZERO_STRUCT(r);
1820         r.in.server = &server;
1821
1822         torture_assert_ntstatus_ok(tctx,
1823                                    dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
1824                                    "AbortSystemShutdown failed");
1825
1826         torture_assert_werr_ok(tctx, r.out.result,
1827                                "AbortSystemShutdown failed");
1828
1829         return true;
1830 }
1831
1832 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1833                                         struct dcerpc_pipe *p)
1834 {
1835         struct winreg_InitiateSystemShutdown r;
1836         uint16_t hostname = 0x0;
1837         struct dcerpc_binding_handle *b = p->binding_handle;
1838
1839         ZERO_STRUCT(r);
1840         r.in.hostname = &hostname;
1841         r.in.message = talloc(tctx, struct lsa_StringLarge);
1842         init_lsa_StringLarge(r.in.message, "spottyfood");
1843         r.in.force_apps = 1;
1844         r.in.timeout = 30;
1845         r.in.do_reboot = 1;
1846
1847         torture_assert_ntstatus_ok(tctx,
1848                                    dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
1849                                    "InitiateSystemShutdown failed");
1850
1851         torture_assert_werr_ok(tctx, r.out.result,
1852                                "InitiateSystemShutdown failed");
1853
1854         return test_AbortSystemShutdown(b, tctx);
1855 }
1856
1857
1858 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1859                                           struct dcerpc_pipe *p)
1860 {
1861         struct winreg_InitiateSystemShutdownEx r;
1862         uint16_t hostname = 0x0;
1863         struct dcerpc_binding_handle *b = p->binding_handle;
1864
1865         ZERO_STRUCT(r);
1866         r.in.hostname = &hostname;
1867         r.in.message = talloc(tctx, struct lsa_StringLarge);
1868         init_lsa_StringLarge(r.in.message, "spottyfood");
1869         r.in.force_apps = 1;
1870         r.in.timeout = 30;
1871         r.in.do_reboot = 1;
1872         r.in.reason = 0;
1873
1874         torture_assert_ntstatus_ok(tctx,
1875                 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
1876                 "InitiateSystemShutdownEx failed");
1877
1878         torture_assert_werr_ok(tctx, r.out.result,
1879                                "InitiateSystemShutdownEx failed");
1880
1881         return test_AbortSystemShutdown(b, tctx);
1882 }
1883 #define MAX_DEPTH 2             /* Only go this far down the tree */
1884
1885 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1886                      struct policy_handle *handle, int depth,
1887                      bool test_security)
1888 {
1889         struct dcerpc_binding_handle *b = p->binding_handle;
1890
1891         if (depth == MAX_DEPTH)
1892                 return true;
1893
1894         if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
1895         }
1896
1897         if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
1898         }
1899
1900         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1901         }
1902
1903         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1904         }
1905
1906         if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
1907         }
1908
1909         test_CloseKey(b, tctx, handle);
1910
1911         return true;
1912 }
1913
1914 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
1915                                  struct torture_context *tctx,
1916                                  struct policy_handle *handle)
1917 {
1918         const char *value_name = TEST_VALUE;
1919         uint32_t value = 0x12345678;
1920         uint64_t value2 = 0x12345678;
1921         const char *string = "torture";
1922         DATA_BLOB blob;
1923         enum winreg_Type types[] = {
1924                 REG_DWORD,
1925                 REG_DWORD_BIG_ENDIAN,
1926                 REG_QWORD,
1927                 REG_BINARY,
1928                 REG_SZ,
1929                 REG_MULTI_SZ
1930         };
1931         int t;
1932
1933         torture_comment(tctx, "Testing SetValue (standard formats)\n");
1934
1935         for (t=0; t < ARRAY_SIZE(types); t++) {
1936
1937                 enum winreg_Type w_type;
1938                 uint32_t w_size, w_length;
1939                 uint8_t *w_data;
1940
1941                 switch (types[t]) {
1942                 case REG_DWORD:
1943                 case REG_DWORD_BIG_ENDIAN:
1944                         blob = data_blob_talloc_zero(tctx, 4);
1945                         SIVAL(blob.data, 0, value);
1946                         break;
1947                 case REG_QWORD:
1948                         blob = data_blob_talloc_zero(tctx, 8);
1949                         SBVAL(blob.data, 0, value2);
1950                         break;
1951                 case REG_BINARY:
1952                         blob = data_blob_string_const("binary_blob");
1953                         break;
1954                 case REG_SZ:
1955                         torture_assert(tctx,
1956                                 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1957                                                                   CH_UNIX, CH_UTF16,
1958                                                                   string,
1959                                                                   strlen(string)+1,
1960                                                                   (void **)&blob.data,
1961                                                                   &blob.length,
1962                                                                   false), "");
1963                         break;
1964                 case REG_MULTI_SZ:
1965                         torture_assert(tctx,
1966                                 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1967                                                                   CH_UNIX, CH_UTF16,
1968                                                                   string,
1969                                                                   strlen(string)+1,
1970                                                                   (void **)&blob.data,
1971                                                                   &blob.length,
1972                                                                   false), "");
1973                         torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1974                         memset(&blob.data[blob.length - 2], '\0', 2);
1975                         break;
1976                 default:
1977                         break;
1978                 }
1979
1980                 torture_assert(tctx,
1981                         test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
1982                         "test_SetValue failed");
1983                 torture_assert(tctx,
1984                         test_QueryValue_full(b, tctx, handle, value_name, true),
1985                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1986                 torture_assert(tctx,
1987                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1988                         "test_winreg_QueryValue failed");
1989                 torture_assert(tctx,
1990                         test_DeleteValue(b, tctx, handle, value_name),
1991                         "test_DeleteValue failed");
1992
1993                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1994                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1995                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1996                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1997         }
1998
1999         torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2000
2001         return true;
2002 }
2003
2004 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2005
2006 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2007                                    struct torture_context *tctx,
2008                                    struct policy_handle *handle)
2009 {
2010         const char *value_name = TEST_VALUE;
2011         enum winreg_Type types[] = {
2012                 REG_NONE,
2013                 REG_SZ,
2014                 REG_EXPAND_SZ,
2015                 REG_BINARY,
2016                 REG_DWORD,
2017                 REG_DWORD_BIG_ENDIAN,
2018                 REG_LINK,
2019                 REG_MULTI_SZ,
2020                 REG_RESOURCE_LIST,
2021                 REG_FULL_RESOURCE_DESCRIPTOR,
2022                 REG_RESOURCE_REQUIREMENTS_LIST,
2023                 REG_QWORD,
2024                 12,
2025                 13,
2026                 14,
2027                 55,
2028                 123456,
2029                 653210,
2030                 __LINE__
2031         };
2032         int t, l;
2033
2034         if (torture_setting_bool(tctx, "samba3", false) ||
2035             torture_setting_bool(tctx, "samba4", false)) {
2036                 torture_skip(tctx, "skipping extended SetValue test against Samba");
2037         }
2038
2039         torture_comment(tctx, "Testing SetValue (extended formats)\n");
2040
2041         for (t=0; t < ARRAY_SIZE(types); t++) {
2042         for (l=0; l < 32; l++) {
2043
2044                 enum winreg_Type w_type;
2045                 uint32_t w_size, w_length;
2046                 uint8_t *w_data;
2047
2048                 uint32_t size;
2049                 uint8_t *data;
2050
2051                 size = l;
2052                 data = talloc_array(tctx, uint8_t, size);
2053
2054                 generate_random_buffer(data, size);
2055
2056                 torture_assert(tctx,
2057                         test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2058                         "test_SetValue failed");
2059
2060                 torture_assert(tctx,
2061                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2062                         "test_winreg_QueryValue failed");
2063
2064                 torture_assert(tctx,
2065                         test_DeleteValue(b, tctx, handle, value_name),
2066                         "test_DeleteValue failed");
2067
2068                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2069                 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2070                 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2071                 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2072         }
2073         }
2074
2075         torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2076
2077         return true;
2078 }
2079
2080 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2081 #define VALUE_CURRENT_VERSION "CurrentVersion"
2082
2083 static bool test_HKLM_wellknown(struct torture_context *tctx,
2084                                 struct dcerpc_binding_handle *b,
2085                                 struct policy_handle *handle)
2086 {
2087         struct policy_handle newhandle;
2088
2089         /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2090         if (torture_setting_bool(tctx, "samba3", false)) {
2091                 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2092                                KEY_CURRENT_VERSION,
2093                                REG_OPTION_NON_VOLATILE,
2094                                KEY_QUERY_VALUE,
2095                                &newhandle,
2096                                WERR_OK),
2097                         "failed to open current version key");
2098         } else {
2099                 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2100                         "failed to open current version key");
2101         }
2102
2103         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2104                 "failed to query current version");
2105         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2106                 "failed to query current version");
2107         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2108                 "test_QueryValue_full for NULL value failed");
2109         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2110                 "test_QueryValue_full for \"\" value failed");
2111
2112         torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2113                 "failed to close current version key");
2114
2115         return true;
2116 }
2117
2118 static bool test_volatile_keys(struct torture_context *tctx,
2119                                struct dcerpc_binding_handle *b,
2120                                struct policy_handle *handle)
2121 {
2122         struct policy_handle new_handle;
2123         enum winreg_CreateAction action_taken;
2124
2125         torture_comment(tctx, "Testing REG_OPTION_VOLATILE key\n");
2126
2127         torture_assert(tctx,
2128                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2129                                     REG_OPTION_VOLATILE,
2130                                     SEC_FLAG_MAXIMUM_ALLOWED,
2131                                     NULL,
2132                                     WERR_OK,
2133                                     &action_taken,
2134                                     &new_handle),
2135                 "failed to create REG_OPTION_VOLATILE type key");
2136
2137         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2138
2139         torture_assert(tctx,
2140                 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2141                                     REG_OPTION_NON_VOLATILE,
2142                                     SEC_FLAG_MAXIMUM_ALLOWED,
2143                                     NULL,
2144                                     WERR_CHILD_MUST_BE_VOLATILE,
2145                                     NULL,
2146                                     NULL),
2147                 "failed to fail create REG_OPTION_VOLATILE type key");
2148
2149         torture_assert(tctx,
2150                 test_CloseKey(b, tctx, &new_handle),
2151                 "failed to close");
2152
2153         torture_assert(tctx,
2154                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2155                                   REG_OPTION_NON_VOLATILE,
2156                                   SEC_FLAG_MAXIMUM_ALLOWED,
2157                                   &new_handle,
2158                                   WERR_OK),
2159                 "failed to open volatile key");
2160
2161         torture_assert(tctx,
2162                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2163                 "failed to delete key");
2164
2165         torture_assert(tctx,
2166                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2167                                     REG_OPTION_VOLATILE,
2168                                     SEC_FLAG_MAXIMUM_ALLOWED,
2169                                     NULL,
2170                                     WERR_OK,
2171                                     &action_taken,
2172                                     &new_handle),
2173                 "failed to create REG_OPTION_VOLATILE type key");
2174
2175         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2176
2177         torture_assert(tctx,
2178                 test_CloseKey(b, tctx, &new_handle),
2179                 "failed to close");
2180
2181         torture_assert(tctx,
2182                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2183                                   REG_OPTION_VOLATILE,
2184                                   SEC_FLAG_MAXIMUM_ALLOWED,
2185                                   &new_handle,
2186                                   WERR_OK),
2187                 "failed to open volatile key");
2188
2189         torture_assert(tctx,
2190                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2191                 "failed to delete key");
2192
2193         torture_assert(tctx,
2194                 test_CloseKey(b, tctx, &new_handle),
2195                 "failed to close");
2196
2197         return true;
2198 }
2199
2200 static bool test_symlink_keys(struct torture_context *tctx,
2201                               struct dcerpc_binding_handle *b,
2202                               struct policy_handle *handle)
2203 {
2204         struct policy_handle new_handle;
2205         enum winreg_CreateAction action_taken;
2206         DATA_BLOB blob;
2207         /* symlink destination needs to be a kernel mode registry path */
2208         const char *dest = "\\Registry\\MACHINE\\SOFTWARE\\foo";
2209
2210         /* disable until we know how to *not* screw up a windows registry */
2211         torture_skip(tctx, "symlink test disabled");
2212
2213         torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2214
2215         test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK);
2216
2217         torture_assert(tctx,
2218                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_SYMLINK, NULL,
2219                                     REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2220                                     SEC_FLAG_MAXIMUM_ALLOWED,
2221                                     NULL,
2222                                     WERR_OK,
2223                                     &action_taken,
2224                                     &new_handle),
2225                 "failed to create REG_OPTION_CREATE_LINK type key");
2226
2227         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2228
2229         torture_assert(tctx,
2230                 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2231                                       dest, strlen(dest), /* not NULL terminated */
2232                                       &blob.data, &blob.length,
2233                                       false),
2234                 "failed to convert");
2235
2236         torture_assert(tctx,
2237                 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2238                 "failed to create SymbolicLinkValue value");
2239
2240         torture_assert(tctx,
2241                 test_CloseKey(b, tctx, &new_handle),
2242                 "failed to close");
2243
2244         torture_assert(tctx,
2245                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_SYMLINK,
2246                                   REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2247                                   SEC_FLAG_MAXIMUM_ALLOWED,
2248                                   &new_handle,
2249                                   WERR_OK),
2250                 "failed to open symlink key");
2251
2252         torture_assert(tctx,
2253                 test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK),
2254                 "failed to delete key");
2255
2256         return true;
2257 }
2258
2259 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2260                                     struct dcerpc_binding_handle *b,
2261                                     struct policy_handle *handle)
2262 {
2263
2264         if (torture_setting_bool(tctx, "samba3", false) ||
2265             torture_setting_bool(tctx, "samba4", false)) {
2266                 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2267         }
2268
2269         torture_assert(tctx,
2270                 test_volatile_keys(tctx, b, handle),
2271                 "failed to test volatile keys");
2272
2273         torture_assert(tctx,
2274                 test_symlink_keys(tctx, b, handle),
2275                 "failed to test symlink keys");
2276
2277         return true;
2278 }
2279
2280 static bool test_key_base(struct torture_context *tctx,
2281                           struct dcerpc_binding_handle *b,
2282                           struct policy_handle *handle)
2283 {
2284         struct policy_handle newhandle;
2285         bool ret = true, created = false, deleted = false;
2286         bool created3 = false;
2287
2288         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2289
2290         if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2291                 torture_comment(tctx,
2292                                 "CreateKey (TEST_KEY_BASE) failed\n");
2293         }
2294
2295         if (!test_CreateKey(b, tctx, handle, TEST_KEY1, NULL)) {
2296                 torture_comment(tctx,
2297                                 "CreateKey failed - not considering a failure\n");
2298         } else {
2299                 created = true;
2300         }
2301
2302         if (created) {
2303                 if (!test_FlushKey(b, tctx, handle)) {
2304                         torture_comment(tctx, "FlushKey failed\n");
2305                         ret = false;
2306                 }
2307
2308                 if (!test_OpenKey(b, tctx, handle, TEST_KEY1, &newhandle)) {
2309                         torture_fail(tctx,
2310                                      "CreateKey failed (OpenKey after Create didn't work)\n");
2311                 }
2312
2313                 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2314                         "simple SetValue test failed");
2315                 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2316                         "extended SetValue test failed");
2317                 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle),
2318                         "keytype test failed");
2319
2320                 if (!test_CloseKey(b, tctx, &newhandle)) {
2321                         torture_fail(tctx,
2322                                      "CreateKey failed (CloseKey after Open didn't work)\n");
2323                 }
2324
2325                 if (!test_DeleteKey(b, tctx, handle, TEST_KEY1)) {
2326                         torture_comment(tctx, "DeleteKey failed\n");
2327                         ret = false;
2328                 } else {
2329                         deleted = true;
2330                 }
2331
2332                 if (!test_FlushKey(b, tctx, handle)) {
2333                         torture_comment(tctx, "FlushKey failed\n");
2334                         ret = false;
2335                 }
2336
2337                 if (deleted) {
2338                         if (!test_OpenKey_opts(tctx, b, handle, TEST_KEY1,
2339                                                REG_OPTION_NON_VOLATILE,
2340                                                SEC_FLAG_MAXIMUM_ALLOWED,
2341                                                &newhandle,
2342                                                WERR_BADFILE)) {
2343                                 torture_comment(tctx,
2344                                                 "DeleteKey failed (OpenKey after Delete "
2345                                                 "did not return WERR_BADFILE)\n");
2346                                 ret = false;
2347                         }
2348                 }
2349
2350                 if (test_CreateKey(b, tctx, handle, TEST_KEY3, NULL)) {
2351                         created3 = true;
2352                 }
2353
2354                 if (created3) {
2355                         if (test_CreateKey(b, tctx, handle, TEST_SUBKEY, NULL)) {
2356                                 if (!test_DeleteKey(b, tctx, handle, TEST_SUBKEY)) {
2357                                         torture_comment(tctx, "DeleteKey failed\n");
2358                                         ret = false;
2359                                 }
2360                         }
2361
2362                         if (!test_DeleteKey(b, tctx, handle, TEST_KEY3)) {
2363                                 torture_comment(tctx, "DeleteKey failed\n");
2364                                 ret = false;
2365                         }
2366                 }
2367         }
2368
2369         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2370
2371         return ret;
2372 }
2373
2374 static bool test_key_base_sd(struct torture_context *tctx,
2375                              struct dcerpc_pipe *p,
2376                              struct policy_handle *handle)
2377 {
2378         struct policy_handle newhandle;
2379         bool ret = true, created2 = false, created4 = false;
2380         struct dcerpc_binding_handle *b = p->binding_handle;
2381
2382         if (torture_setting_bool(tctx, "samba3", false) ||
2383             torture_setting_bool(tctx, "samba4", false)) {
2384                 torture_skip(tctx, "skipping security descriptor tests against Samba");
2385         }
2386
2387         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2388
2389         if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2390                 torture_comment(tctx,
2391                                 "CreateKey (TEST_KEY_BASE) failed\n");
2392         }
2393
2394         if (test_CreateKey_sd(b, tctx, handle, TEST_KEY2,
2395                               NULL, &newhandle)) {
2396                 created2 = true;
2397         }
2398
2399         if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2400                 torture_comment(tctx, "CloseKey failed\n");
2401                 ret = false;
2402         }
2403
2404         if (test_CreateKey_sd(b, tctx, handle, TEST_KEY4, NULL, &newhandle)) {
2405                 created4 = true;
2406         }
2407
2408         if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2409                 torture_comment(tctx, "CloseKey failed\n");
2410                 ret = false;
2411         }
2412
2413         if (created4 && !test_SecurityDescriptors(p, tctx, handle, TEST_KEY4)) {
2414                 ret = false;
2415         }
2416
2417         if (created4 && !test_DeleteKey(b, tctx, handle, TEST_KEY4)) {
2418                 torture_comment(tctx, "DeleteKey failed\n");
2419                 ret = false;
2420         }
2421
2422         if (created2 && !test_DeleteKey(b, tctx, handle, TEST_KEY2)) {
2423                 torture_comment(tctx, "DeleteKey failed\n");
2424                 ret = false;
2425         }
2426
2427         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2428
2429         return ret;
2430 }
2431
2432 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2433                       void *userdata)
2434 {
2435         struct policy_handle handle;
2436         bool ret = true;
2437         struct winreg_OpenHKLM r;
2438         struct dcerpc_binding_handle *b = p->binding_handle;
2439
2440         winreg_open_fn open_fn = (winreg_open_fn)userdata;
2441
2442         r.in.system_name = 0;
2443         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2444         r.out.handle = &handle;
2445
2446         torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2447                                    "open");
2448
2449         if (!test_GetVersion(b, tctx, &handle)) {
2450                 torture_comment(tctx, "GetVersion failed\n");
2451                 ret = false;
2452         }
2453
2454         if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
2455                 torture_assert(tctx,
2456                         test_HKLM_wellknown(tctx, b, &handle),
2457                         "failed to test HKLM wellknown keys");
2458         }
2459
2460         if (!test_key_base(tctx, b, &handle)) {
2461                 torture_warning(tctx, "failed to test TEST_KEY_BASE");
2462                 ret = false;
2463         }
2464
2465         if (!test_key_base_sd(tctx, p, &handle)) {
2466                 torture_warning(tctx, "failed to test TEST_KEY_BASE sd");
2467                 ret = false;
2468         }
2469
2470         /* The HKCR hive has a very large fanout */
2471         if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
2472                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2473                         ret = false;
2474                 }
2475         } else {
2476                 if (!test_key(p, tctx, &handle, 0, false)) {
2477                         ret = false;
2478                 }
2479         }
2480
2481         return ret;
2482 }
2483
2484 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2485 {
2486         struct torture_rpc_tcase *tcase;
2487         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2488         struct torture_test *test;
2489
2490         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2491                                                   &ndr_table_winreg);
2492
2493         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2494                                           test_InitiateSystemShutdown);
2495         test->dangerous = true;
2496
2497         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2498                                           test_InitiateSystemShutdownEx);
2499         test->dangerous = true;
2500
2501         torture_rpc_tcase_add_test_ex(tcase, "HKLM",
2502                                       test_Open,
2503                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2504         torture_rpc_tcase_add_test_ex(tcase, "HKU",
2505                                       test_Open,
2506                                       (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2507         torture_rpc_tcase_add_test_ex(tcase, "HKCR",
2508                                       test_Open,
2509                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2510         torture_rpc_tcase_add_test_ex(tcase, "HKCU",
2511                                       test_Open,
2512                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
2513
2514         return suite;
2515 }