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