s4-smbtorture: when creating winreg-symlinks during a test, it is very wise to make...
[amitay/samba.git] / source4 / torture / rpc / winreg.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for winreg rpc operations
4
5    Copyright (C) Tim Potter 2003
6    Copyright (C) Jelmer Vernooij 2004-2007
7    Copyright (C) Günther Deschner 2007
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/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_KEYTYPE_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, NULL, 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, NULL, 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, NULL, 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_KEYTYPE_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_KEYTYPE_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_KEYTYPE_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_KEYTYPE_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         NTSTATUS status;
1605         uint32_t bufsize=0;
1606
1607         ZERO_STRUCT(r);
1608         r.in.key_handle = handle;
1609         r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1610         r.in.values[0].name = talloc(tctx, struct winreg_String);
1611         r.in.values[0].name->name = valuename;
1612         r.in.values[0].offset = 0;
1613         r.in.values[0].length = 0;
1614         r.in.values[0].type = 0;
1615
1616         r.in.num_values = 1;
1617         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1618         *r.in.buffer_size = bufsize;
1619         do {
1620                 *r.in.buffer_size = bufsize;
1621                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1622                                                                *r.in.buffer_size);
1623
1624                 status = dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r);
1625
1626                 if(NT_STATUS_IS_ERR(status))
1627                         torture_fail(tctx, "QueryMultipleValues failed");
1628
1629                 talloc_free(r.in.buffer);
1630                 bufsize += 0x20;
1631         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1632
1633         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1634
1635         return true;
1636 }
1637
1638 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1639                             struct torture_context *tctx,
1640                             struct policy_handle *handle,
1641                             const char *valuename)
1642 {
1643         struct winreg_QueryValue r;
1644         NTSTATUS status;
1645         enum winreg_Type zero_type = 0;
1646         uint32_t offered = 0xfff;
1647         uint32_t zero = 0;
1648
1649         ZERO_STRUCT(r);
1650         r.in.handle = handle;
1651         r.in.data = NULL;
1652         r.in.value_name = talloc_zero(tctx, struct winreg_String);
1653         r.in.value_name->name = valuename;
1654         r.in.type = &zero_type;
1655         r.in.data_size = &offered;
1656         r.in.data_length = &zero;
1657
1658         status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1659         if (NT_STATUS_IS_ERR(status)) {
1660                 torture_fail(tctx, "QueryValue failed");
1661         }
1662
1663         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1664
1665         return true;
1666 }
1667
1668 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1669                                  struct torture_context *tctx,
1670                                  struct policy_handle *handle,
1671                                  const char *valuename,
1672                                  bool existing_value)
1673 {
1674         struct winreg_QueryValue r;
1675         struct winreg_String value_name;
1676         enum winreg_Type type = REG_NONE;
1677         uint32_t data_size = 0;
1678         uint32_t real_data_size = 0;
1679         uint32_t data_length = 0;
1680         uint8_t *data = NULL;
1681         WERROR expected_error = WERR_BADFILE;
1682
1683         if (valuename == NULL) {
1684                 expected_error = WERR_INVALID_PARAM;
1685         }
1686
1687         ZERO_STRUCT(r);
1688
1689         init_winreg_String(&value_name, NULL);
1690
1691         torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1692
1693         r.in.handle = handle;
1694         r.in.value_name = &value_name;
1695
1696         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1697         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1698                 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1699
1700         init_winreg_String(&value_name, valuename);
1701         r.in.value_name = &value_name;
1702
1703         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1704                 "QueryValue failed");
1705         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1706                 "QueryValue failed");
1707
1708         r.in.type = &type;
1709         r.out.type = &type;
1710         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1711                 "QueryValue failed");
1712         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1713                 "QueryValue failed");
1714
1715         r.in.data_length = &data_length;
1716         r.out.data_length = &data_length;
1717         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1718                 "QueryValue failed");
1719         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1720                 "QueryValue failed");
1721
1722         r.in.data_size = &data_size;
1723         r.out.data_size = &data_size;
1724         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1725                 "QueryValue failed");
1726         if (existing_value) {
1727                 torture_assert_werr_ok(tctx, r.out.result,
1728                         "QueryValue failed");
1729         } else {
1730                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1731                         "QueryValue failed");
1732         }
1733
1734         real_data_size = *r.out.data_size;
1735
1736         data = talloc_zero_array(tctx, uint8_t, 0);
1737         r.in.data = data;
1738         r.out.data = data;
1739         *r.in.data_size = 0;
1740         *r.out.data_size = 0;
1741         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1742                 "QueryValue failed");
1743         if (existing_value) {
1744                 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1745                         "QueryValue failed");
1746         } else {
1747                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1748                         "QueryValue failed");
1749         }
1750
1751         data = talloc_zero_array(tctx, uint8_t, real_data_size);
1752         r.in.data = data;
1753         r.out.data = data;
1754         r.in.data_size = &real_data_size;
1755         r.out.data_size = &real_data_size;
1756         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1757                 "QueryValue failed");
1758         if (existing_value) {
1759                 torture_assert_werr_ok(tctx, r.out.result,
1760                         "QueryValue failed");
1761         } else {
1762                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1763                         "QueryValue failed");
1764         }
1765
1766         return true;
1767 }
1768
1769 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1770                            struct torture_context *tctx,
1771                            struct policy_handle *handle, int max_valnamelen,
1772                            int max_valbufsize)
1773 {
1774         struct winreg_EnumValue r;
1775         enum winreg_Type type = 0;
1776         uint32_t size = max_valbufsize, zero = 0;
1777         bool ret = true;
1778         uint8_t buf8;
1779         struct winreg_ValNameBuf name;
1780
1781         name.name   = "";
1782         name.size   = 1024;
1783
1784         ZERO_STRUCT(r);
1785         r.in.handle = handle;
1786         r.in.enum_index = 0;
1787         r.in.name = &name;
1788         r.out.name = &name;
1789         r.in.type = &type;
1790         r.in.value = &buf8;
1791         r.in.length = &zero;
1792         r.in.size = &size;
1793
1794         do {
1795                 torture_assert_ntstatus_ok(tctx,
1796                                            dcerpc_winreg_EnumValue_r(b, tctx, &r),
1797                                            "EnumValue failed");
1798
1799                 if (W_ERROR_IS_OK(r.out.result)) {
1800                         ret &= test_QueryValue(b, tctx, handle,
1801                                                r.out.name->name);
1802                         ret &= test_QueryMultipleValues(b, tctx, handle,
1803                                                         r.out.name->name);
1804                 }
1805
1806                 r.in.enum_index++;
1807         } while (W_ERROR_IS_OK(r.out.result));
1808
1809         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1810                                   "EnumValue failed");
1811
1812         return ret;
1813 }
1814
1815 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
1816                                      struct torture_context *tctx)
1817 {
1818         struct winreg_AbortSystemShutdown r;
1819         uint16_t server = 0x0;
1820
1821         ZERO_STRUCT(r);
1822         r.in.server = &server;
1823
1824         torture_assert_ntstatus_ok(tctx,
1825                                    dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
1826                                    "AbortSystemShutdown failed");
1827
1828         torture_assert_werr_ok(tctx, r.out.result,
1829                                "AbortSystemShutdown failed");
1830
1831         return true;
1832 }
1833
1834 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1835                                         struct dcerpc_pipe *p)
1836 {
1837         struct winreg_InitiateSystemShutdown r;
1838         uint16_t hostname = 0x0;
1839         struct dcerpc_binding_handle *b = p->binding_handle;
1840
1841         ZERO_STRUCT(r);
1842         r.in.hostname = &hostname;
1843         r.in.message = talloc(tctx, struct lsa_StringLarge);
1844         init_lsa_StringLarge(r.in.message, "spottyfood");
1845         r.in.force_apps = 1;
1846         r.in.timeout = 30;
1847         r.in.do_reboot = 1;
1848
1849         torture_assert_ntstatus_ok(tctx,
1850                                    dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
1851                                    "InitiateSystemShutdown failed");
1852
1853         torture_assert_werr_ok(tctx, r.out.result,
1854                                "InitiateSystemShutdown failed");
1855
1856         return test_AbortSystemShutdown(b, tctx);
1857 }
1858
1859
1860 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1861                                           struct dcerpc_pipe *p)
1862 {
1863         struct winreg_InitiateSystemShutdownEx r;
1864         uint16_t hostname = 0x0;
1865         struct dcerpc_binding_handle *b = p->binding_handle;
1866
1867         ZERO_STRUCT(r);
1868         r.in.hostname = &hostname;
1869         r.in.message = talloc(tctx, struct lsa_StringLarge);
1870         init_lsa_StringLarge(r.in.message, "spottyfood");
1871         r.in.force_apps = 1;
1872         r.in.timeout = 30;
1873         r.in.do_reboot = 1;
1874         r.in.reason = 0;
1875
1876         torture_assert_ntstatus_ok(tctx,
1877                 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
1878                 "InitiateSystemShutdownEx failed");
1879
1880         torture_assert_werr_ok(tctx, r.out.result,
1881                                "InitiateSystemShutdownEx failed");
1882
1883         return test_AbortSystemShutdown(b, tctx);
1884 }
1885 #define MAX_DEPTH 2             /* Only go this far down the tree */
1886
1887 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1888                      struct policy_handle *handle, int depth,
1889                      bool test_security)
1890 {
1891         struct dcerpc_binding_handle *b = p->binding_handle;
1892
1893         if (depth == MAX_DEPTH)
1894                 return true;
1895
1896         if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
1897         }
1898
1899         if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
1900         }
1901
1902         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1903         }
1904
1905         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1906         }
1907
1908         if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
1909         }
1910
1911         test_CloseKey(b, tctx, handle);
1912
1913         return true;
1914 }
1915
1916 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
1917                                  struct torture_context *tctx,
1918                                  struct policy_handle *handle)
1919 {
1920         const char *value_name = TEST_VALUE;
1921         uint32_t value = 0x12345678;
1922         uint64_t value2 = 0x12345678;
1923         const char *string = "torture";
1924         DATA_BLOB blob;
1925         enum winreg_Type types[] = {
1926                 REG_DWORD,
1927                 REG_DWORD_BIG_ENDIAN,
1928                 REG_QWORD,
1929                 REG_BINARY,
1930                 REG_SZ,
1931                 REG_MULTI_SZ
1932         };
1933         int t;
1934
1935         torture_comment(tctx, "Testing SetValue (standard formats)\n");
1936
1937         for (t=0; t < ARRAY_SIZE(types); t++) {
1938
1939                 enum winreg_Type w_type;
1940                 uint32_t w_size, w_length;
1941                 uint8_t *w_data;
1942
1943                 switch (types[t]) {
1944                 case REG_DWORD:
1945                 case REG_DWORD_BIG_ENDIAN:
1946                         blob = data_blob_talloc_zero(tctx, 4);
1947                         SIVAL(blob.data, 0, value);
1948                         break;
1949                 case REG_QWORD:
1950                         blob = data_blob_talloc_zero(tctx, 8);
1951                         SBVAL(blob.data, 0, value2);
1952                         break;
1953                 case REG_BINARY:
1954                         blob = data_blob_string_const("binary_blob");
1955                         break;
1956                 case REG_SZ:
1957                         torture_assert(tctx,
1958                                 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1959                                                                   CH_UNIX, CH_UTF16,
1960                                                                   string,
1961                                                                   strlen(string)+1,
1962                                                                   (void **)&blob.data,
1963                                                                   &blob.length,
1964                                                                   false), "");
1965                         break;
1966                 case REG_MULTI_SZ:
1967                         torture_assert(tctx,
1968                                 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1969                                                                   CH_UNIX, CH_UTF16,
1970                                                                   string,
1971                                                                   strlen(string)+1,
1972                                                                   (void **)&blob.data,
1973                                                                   &blob.length,
1974                                                                   false), "");
1975                         torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1976                         memset(&blob.data[blob.length - 2], '\0', 2);
1977                         break;
1978                 default:
1979                         break;
1980                 }
1981
1982                 torture_assert(tctx,
1983                         test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
1984                         "test_SetValue failed");
1985                 torture_assert(tctx,
1986                         test_QueryValue_full(b, tctx, handle, value_name, true),
1987                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1988                 torture_assert(tctx,
1989                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1990                         "test_winreg_QueryValue failed");
1991                 torture_assert(tctx,
1992                         test_DeleteValue(b, tctx, handle, value_name),
1993                         "test_DeleteValue failed");
1994
1995                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1996                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1997                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1998                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1999         }
2000
2001         torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2002
2003         return true;
2004 }
2005
2006 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2007
2008 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2009                                    struct torture_context *tctx,
2010                                    struct policy_handle *handle)
2011 {
2012         const char *value_name = TEST_VALUE;
2013         enum winreg_Type types[] = {
2014                 REG_NONE,
2015                 REG_SZ,
2016                 REG_EXPAND_SZ,
2017                 REG_BINARY,
2018                 REG_DWORD,
2019                 REG_DWORD_BIG_ENDIAN,
2020                 REG_LINK,
2021                 REG_MULTI_SZ,
2022                 REG_RESOURCE_LIST,
2023                 REG_FULL_RESOURCE_DESCRIPTOR,
2024                 REG_RESOURCE_REQUIREMENTS_LIST,
2025                 REG_QWORD,
2026                 12,
2027                 13,
2028                 14,
2029                 55,
2030                 123456,
2031                 653210,
2032                 __LINE__
2033         };
2034         int t, l;
2035
2036         if (torture_setting_bool(tctx, "samba3", false) ||
2037             torture_setting_bool(tctx, "samba4", false)) {
2038                 torture_skip(tctx, "skipping extended SetValue test against Samba");
2039         }
2040
2041         torture_comment(tctx, "Testing SetValue (extended formats)\n");
2042
2043         for (t=0; t < ARRAY_SIZE(types); t++) {
2044         for (l=0; l < 32; l++) {
2045
2046                 enum winreg_Type w_type;
2047                 uint32_t w_size, w_length;
2048                 uint8_t *w_data;
2049
2050                 uint32_t size;
2051                 uint8_t *data;
2052
2053                 size = l;
2054                 data = talloc_array(tctx, uint8_t, size);
2055
2056                 generate_random_buffer(data, size);
2057
2058                 torture_assert(tctx,
2059                         test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2060                         "test_SetValue failed");
2061
2062                 torture_assert(tctx,
2063                         test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2064                         "test_winreg_QueryValue failed");
2065
2066                 torture_assert(tctx,
2067                         test_DeleteValue(b, tctx, handle, value_name),
2068                         "test_DeleteValue failed");
2069
2070                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2071                 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2072                 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2073                 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2074         }
2075         }
2076
2077         torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2078
2079         return true;
2080 }
2081
2082 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2083 #define VALUE_CURRENT_VERSION "CurrentVersion"
2084
2085 static bool test_HKLM_wellknown(struct torture_context *tctx,
2086                                 struct dcerpc_binding_handle *b,
2087                                 struct policy_handle *handle)
2088 {
2089         struct policy_handle newhandle;
2090
2091         /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2092         if (torture_setting_bool(tctx, "samba3", false)) {
2093                 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2094                                KEY_CURRENT_VERSION,
2095                                REG_KEYTYPE_NON_VOLATILE,
2096                                KEY_QUERY_VALUE,
2097                                &newhandle,
2098                                WERR_OK),
2099                         "failed to open current version key");
2100         } else {
2101                 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2102                         "failed to open current version key");
2103         }
2104
2105         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2106                 "failed to query current version");
2107         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2108                 "failed to query current version");
2109         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2110                 "test_QueryValue_full for NULL value failed");
2111         torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2112                 "test_QueryValue_full for \"\" value failed");
2113
2114         torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2115                 "failed to close current version key");
2116
2117         return true;
2118 }
2119
2120 static bool test_volatile_keys(struct torture_context *tctx,
2121                                struct dcerpc_binding_handle *b,
2122                                struct policy_handle *handle)
2123 {
2124         struct policy_handle new_handle;
2125         enum winreg_CreateAction action_taken;
2126
2127         torture_comment(tctx, "Testing REG_KEYTYPE_VOLATILE key\n");
2128
2129         torture_assert(tctx,
2130                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2131                                     REG_KEYTYPE_VOLATILE,
2132                                     SEC_FLAG_MAXIMUM_ALLOWED,
2133                                     NULL,
2134                                     WERR_OK,
2135                                     &action_taken,
2136                                     &new_handle),
2137                 "failed to create REG_KEYTYPE_VOLATILE type key");
2138
2139         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2140
2141         torture_assert(tctx,
2142                 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2143                                     REG_KEYTYPE_NON_VOLATILE,
2144                                     SEC_FLAG_MAXIMUM_ALLOWED,
2145                                     NULL,
2146                                     WERR_CHILD_MUST_BE_VOLATILE,
2147                                     NULL,
2148                                     NULL),
2149                 "failed to fail create REG_KEYTYPE_VOLATILE type key");
2150
2151         torture_assert(tctx,
2152                 test_CloseKey(b, tctx, &new_handle),
2153                 "failed to close");
2154
2155         torture_assert(tctx,
2156                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2157                                   REG_KEYTYPE_NON_VOLATILE,
2158                                   SEC_FLAG_MAXIMUM_ALLOWED,
2159                                   &new_handle,
2160                                   WERR_OK),
2161                 "failed to open volatile key");
2162
2163         torture_assert(tctx,
2164                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2165                 "failed to delete key");
2166
2167         torture_assert(tctx,
2168                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2169                                     REG_KEYTYPE_VOLATILE,
2170                                     SEC_FLAG_MAXIMUM_ALLOWED,
2171                                     NULL,
2172                                     WERR_OK,
2173                                     &action_taken,
2174                                     &new_handle),
2175                 "failed to create REG_KEYTYPE_VOLATILE type key");
2176
2177         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2178
2179         torture_assert(tctx,
2180                 test_CloseKey(b, tctx, &new_handle),
2181                 "failed to close");
2182
2183         torture_assert(tctx,
2184                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2185                                   REG_KEYTYPE_VOLATILE,
2186                                   SEC_FLAG_MAXIMUM_ALLOWED,
2187                                   &new_handle,
2188                                   WERR_OK),
2189                 "failed to open volatile key");
2190
2191         torture_assert(tctx,
2192                 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2193                 "failed to delete key");
2194
2195         torture_assert(tctx,
2196                 test_CloseKey(b, tctx, &new_handle),
2197                 "failed to close");
2198
2199         return true;
2200 }
2201
2202 static bool test_symlink_keys(struct torture_context *tctx,
2203                               struct dcerpc_binding_handle *b,
2204                               struct policy_handle *handle)
2205 {
2206         struct policy_handle new_handle;
2207         enum winreg_CreateAction action_taken;
2208         DATA_BLOB blob;
2209         /* symlink destination needs to be a kernel mode registry path */
2210         const char *dest = "\\Registry\\MACHINE\\SOFTWARE\\foo";
2211
2212         /* disable until we know how to *not* screw up a windows registry */
2213         torture_skip(tctx, "symlink test disabled");
2214
2215         torture_comment(tctx, "Testing REG_KEYTYPE_SYMLINK key\n");
2216
2217         test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK);
2218
2219         torture_assert(tctx,
2220                 test_CreateKey_opts(tctx, b, handle, TEST_KEY_SYMLINK, NULL,
2221                                     REG_KEYTYPE_SYMLINK | REG_KEYTYPE_VOLATILE,
2222                                     SEC_FLAG_MAXIMUM_ALLOWED,
2223                                     NULL,
2224                                     WERR_OK,
2225                                     &action_taken,
2226                                     &new_handle),
2227                 "failed to create REG_KEYTYPE_SYMLINK type key");
2228
2229         torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2230
2231         torture_assert(tctx,
2232                 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2233                                       dest, strlen(dest), /* not NULL terminated */
2234                                       &blob.data, &blob.length,
2235                                       false),
2236                 "failed to convert");
2237
2238         torture_assert(tctx,
2239                 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2240                 "failed to create SymbolicLinkValue value");
2241
2242         torture_assert(tctx,
2243                 test_CloseKey(b, tctx, &new_handle),
2244                 "failed to close");
2245
2246         torture_assert(tctx,
2247                 test_OpenKey_opts(tctx, b, handle, TEST_KEY_SYMLINK,
2248                                   REG_KEYTYPE_SYMLINK | REG_KEYTYPE_VOLATILE,
2249                                   SEC_FLAG_MAXIMUM_ALLOWED,
2250                                   &new_handle,
2251                                   WERR_OK),
2252                 "failed to open symlink key");
2253
2254         torture_assert(tctx,
2255                 test_DeleteKey(b, tctx, &new_handle, TEST_KEY_SYMLINK),
2256                 "failed to delete key");
2257
2258         return true;
2259 }
2260
2261 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2262                                     struct dcerpc_binding_handle *b,
2263                                     struct policy_handle *handle)
2264 {
2265
2266         if (torture_setting_bool(tctx, "samba3", false) ||
2267             torture_setting_bool(tctx, "samba4", false)) {
2268                 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2269         }
2270
2271         torture_assert(tctx,
2272                 test_volatile_keys(tctx, b, handle),
2273                 "failed to test volatile keys");
2274
2275         torture_assert(tctx,
2276                 test_symlink_keys(tctx, b, handle),
2277                 "failed to test symlink keys");
2278
2279         return true;
2280 }
2281
2282 static bool test_key_base(struct torture_context *tctx,
2283                           struct dcerpc_binding_handle *b,
2284                           struct policy_handle *handle)
2285 {
2286         struct policy_handle newhandle;
2287         bool ret = true, created = false, deleted = false;
2288         bool created3 = false;
2289
2290         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2291
2292         if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2293                 torture_comment(tctx,
2294                                 "CreateKey (TEST_KEY_BASE) failed\n");
2295         }
2296
2297         if (!test_CreateKey(b, tctx, handle, TEST_KEY1, NULL)) {
2298                 torture_comment(tctx,
2299                                 "CreateKey failed - not considering a failure\n");
2300         } else {
2301                 created = true;
2302         }
2303
2304         if (created) {
2305                 if (!test_FlushKey(b, tctx, handle)) {
2306                         torture_comment(tctx, "FlushKey failed\n");
2307                         ret = false;
2308                 }
2309
2310                 if (!test_OpenKey(b, tctx, handle, TEST_KEY1, &newhandle)) {
2311                         torture_fail(tctx,
2312                                      "CreateKey failed (OpenKey after Create didn't work)\n");
2313                 }
2314
2315                 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2316                         "simple SetValue test failed");
2317                 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2318                         "extended SetValue test failed");
2319                 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle),
2320                         "keytype test failed");
2321
2322                 if (!test_CloseKey(b, tctx, &newhandle)) {
2323                         torture_fail(tctx,
2324                                      "CreateKey failed (CloseKey after Open didn't work)\n");
2325                 }
2326
2327                 if (!test_DeleteKey(b, tctx, handle, TEST_KEY1)) {
2328                         torture_comment(tctx, "DeleteKey failed\n");
2329                         ret = false;
2330                 } else {
2331                         deleted = true;
2332                 }
2333
2334                 if (!test_FlushKey(b, tctx, handle)) {
2335                         torture_comment(tctx, "FlushKey failed\n");
2336                         ret = false;
2337                 }
2338
2339                 if (deleted) {
2340                         if (!test_OpenKey_opts(tctx, b, handle, TEST_KEY1,
2341                                                REG_KEYTYPE_NON_VOLATILE,
2342                                                SEC_FLAG_MAXIMUM_ALLOWED,
2343                                                &newhandle,
2344                                                WERR_BADFILE)) {
2345                                 torture_comment(tctx,
2346                                                 "DeleteKey failed (OpenKey after Delete "
2347                                                 "did not return WERR_BADFILE)\n");
2348                                 ret = false;
2349                         }
2350                 }
2351
2352                 if (test_CreateKey(b, tctx, handle, TEST_KEY3, NULL)) {
2353                         created3 = true;
2354                 }
2355
2356                 if (created3) {
2357                         if (test_CreateKey(b, tctx, handle, TEST_SUBKEY, NULL)) {
2358                                 if (!test_DeleteKey(b, tctx, handle, TEST_SUBKEY)) {
2359                                         torture_comment(tctx, "DeleteKey failed\n");
2360                                         ret = false;
2361                                 }
2362                         }
2363
2364                         if (!test_DeleteKey(b, tctx, handle, TEST_KEY3)) {
2365                                 torture_comment(tctx, "DeleteKey failed\n");
2366                                 ret = false;
2367                         }
2368                 }
2369         }
2370
2371         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2372
2373         return ret;
2374 }
2375
2376 static bool test_key_base_sd(struct torture_context *tctx,
2377                              struct dcerpc_pipe *p,
2378                              struct policy_handle *handle)
2379 {
2380         struct policy_handle newhandle;
2381         bool ret = true, created2 = false, created4 = false;
2382         struct dcerpc_binding_handle *b = p->binding_handle;
2383
2384         if (torture_setting_bool(tctx, "samba3", false) ||
2385             torture_setting_bool(tctx, "samba4", false)) {
2386                 torture_skip(tctx, "skipping security descriptor tests against Samba");
2387         }
2388
2389         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2390
2391         if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2392                 torture_comment(tctx,
2393                                 "CreateKey (TEST_KEY_BASE) failed\n");
2394         }
2395
2396         if (test_CreateKey_sd(b, tctx, handle, TEST_KEY2,
2397                               NULL, &newhandle)) {
2398                 created2 = true;
2399         }
2400
2401         if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2402                 torture_comment(tctx, "CloseKey failed\n");
2403                 ret = false;
2404         }
2405
2406         if (test_CreateKey_sd(b, tctx, handle, TEST_KEY4, NULL, &newhandle)) {
2407                 created4 = true;
2408         }
2409
2410         if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2411                 torture_comment(tctx, "CloseKey failed\n");
2412                 ret = false;
2413         }
2414
2415         if (created4 && !test_SecurityDescriptors(p, tctx, handle, TEST_KEY4)) {
2416                 ret = false;
2417         }
2418
2419         if (created4 && !test_DeleteKey(b, tctx, handle, TEST_KEY4)) {
2420                 torture_comment(tctx, "DeleteKey failed\n");
2421                 ret = false;
2422         }
2423
2424         if (created2 && !test_DeleteKey(b, tctx, handle, TEST_KEY2)) {
2425                 torture_comment(tctx, "DeleteKey failed\n");
2426                 ret = false;
2427         }
2428
2429         test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2430
2431         return ret;
2432 }
2433
2434 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2435                       void *userdata)
2436 {
2437         struct policy_handle handle;
2438         bool ret = true;
2439         struct winreg_OpenHKLM r;
2440         struct dcerpc_binding_handle *b = p->binding_handle;
2441
2442         winreg_open_fn open_fn = userdata;
2443
2444         r.in.system_name = 0;
2445         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2446         r.out.handle = &handle;
2447
2448         torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2449                                    "open");
2450
2451         if (!test_GetVersion(b, tctx, &handle)) {
2452                 torture_comment(tctx, "GetVersion failed\n");
2453                 ret = false;
2454         }
2455
2456         if (open_fn == (void *)dcerpc_winreg_OpenHKLM_r) {
2457                 torture_assert(tctx,
2458                         test_HKLM_wellknown(tctx, b, &handle),
2459                         "failed to test HKLM wellknown keys");
2460         }
2461
2462         if (!test_key_base(tctx, b, &handle)) {
2463                 torture_warning(tctx, "failed to test TEST_KEY_BASE");
2464                 ret = false;
2465         }
2466
2467         if (!test_key_base_sd(tctx, p, &handle)) {
2468                 torture_warning(tctx, "failed to test TEST_KEY_BASE sd");
2469                 ret = false;
2470         }
2471
2472         /* The HKCR hive has a very large fanout */
2473         if (open_fn == (void *)dcerpc_winreg_OpenHKCR_r) {
2474                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2475                         ret = false;
2476                 }
2477         } else {
2478                 if (!test_key(p, tctx, &handle, 0, false)) {
2479                         ret = false;
2480                 }
2481         }
2482
2483         return ret;
2484 }
2485
2486 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2487 {
2488         struct torture_rpc_tcase *tcase;
2489         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2490         struct torture_test *test;
2491
2492         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2493                                                   &ndr_table_winreg);
2494
2495         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2496                                           test_InitiateSystemShutdown);
2497         test->dangerous = true;
2498
2499         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2500                                           test_InitiateSystemShutdownEx);
2501         test->dangerous = true;
2502
2503         torture_rpc_tcase_add_test_ex(tcase, "HKLM",
2504                                       test_Open,
2505                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2506         torture_rpc_tcase_add_test_ex(tcase, "HKU",
2507                                       test_Open,
2508                                       (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2509         torture_rpc_tcase_add_test_ex(tcase, "HKCR",
2510                                       test_Open,
2511                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2512         torture_rpc_tcase_add_test_ex(tcase, "HKCU",
2513                                       test_Open,
2514                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
2515
2516         return suite;
2517 }