s4-smbtorture: skip extended SetValue test against Samba (both dont survive).
[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         NTSTATUS status;
783         bool ret = true;
784
785         torture_comment(tctx, "SecurityDescriptor inheritance\n");
786
787         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
788                 return false;
789         }
790
791         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
792                 return false;
793         }
794
795         sd_orig = security_descriptor_copy(tctx, sd);
796         if (sd_orig == NULL) {
797                 return false;
798         }
799
800         ace = security_ace_create(tctx,
801                                   TEST_SID,
802                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
803                                   SEC_STD_REQUIRED,
804                                   SEC_ACE_FLAG_CONTAINER_INHERIT);
805
806         status = security_descriptor_dacl_add(sd, ace);
807         if (!NT_STATUS_IS_OK(status)) {
808                 printf("failed to add ace: %s\n", nt_errstr(status));
809                 return false;
810         }
811
812         /* FIXME: add further tests for these flags */
813         sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
814                     SEC_DESC_SACL_AUTO_INHERITED;
815
816         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
817                 return false;
818         }
819
820         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
821                 printf("new ACE not present!\n");
822                 return false;
823         }
824
825         if (!test_CloseKey(p, tctx, &new_handle)) {
826                 return false;
827         }
828
829         if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
830                 ret = false;
831                 goto out;
832         }
833
834         if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
835                 ret = false;
836                 goto out;
837         }
838
839         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
840                 printf("inherited ACE not present!\n");
841                 ret = false;
842                 goto out;
843         }
844
845         test_CloseKey(p, tctx, &new_handle);
846         if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
847                 ret = false;
848                 goto out;
849         }
850
851         if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
852                 ret = false;
853                 goto out;
854         }
855
856         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
857                 printf("inherited ACE not present!\n");
858                 ret = false;
859                 goto out;
860         }
861
862  out:
863         test_CloseKey(p, tctx, &new_handle);
864         test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
865         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
866
867         return true;
868 }
869
870 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
871                                                     struct torture_context *tctx,
872                                                     struct policy_handle *handle,
873                                                     const char *key)
874 {
875         /* get sd
876            add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
877            set sd
878            add subkey/subkey
879            get sd
880            check ace
881            get sd from subkey
882            check ace
883            del subkey/subkey
884            del subkey
885            reset sd
886         */
887
888         struct security_descriptor *sd = NULL;
889         struct security_descriptor *sd_orig = NULL;
890         struct security_ace *ace = NULL;
891         struct policy_handle new_handle;
892         struct dom_sid *sid = NULL;
893         NTSTATUS status;
894         bool ret = true;
895         uint8_t ace_flags = 0x0;
896
897         torture_comment(tctx, "SecurityDescriptor inheritance block\n");
898
899         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
900                 return false;
901         }
902
903         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
904                 return false;
905         }
906
907         sd_orig = security_descriptor_copy(tctx, sd);
908         if (sd_orig == NULL) {
909                 return false;
910         }
911
912         ace = security_ace_create(tctx,
913                                   TEST_SID,
914                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
915                                   SEC_STD_REQUIRED,
916                                   SEC_ACE_FLAG_CONTAINER_INHERIT |
917                                   SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
918
919         status = security_descriptor_dacl_add(sd, ace);
920         if (!NT_STATUS_IS_OK(status)) {
921                 printf("failed to add ace: %s\n", nt_errstr(status));
922                 return false;
923         }
924
925         if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
926                 return false;
927         }
928
929         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
930                 printf("new ACE not present!\n");
931                 return false;
932         }
933
934         if (!test_CloseKey(p, tctx, &new_handle)) {
935                 return false;
936         }
937
938         if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
939                 return false;
940         }
941
942         if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
943                 ret = false;
944                 goto out;
945         }
946
947         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
948                 printf("inherited ACE present but should not!\n");
949                 ret = false;
950                 goto out;
951         }
952
953         sid = dom_sid_parse_talloc(tctx, TEST_SID);
954         if (sid == NULL) {
955                 return false;
956         }
957
958         if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
959                 printf("inherited trustee SID present but should not!\n");
960                 ret = false;
961                 goto out;
962         }
963
964         test_CloseKey(p, tctx, &new_handle);
965
966         if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
967                 ret = false;
968                 goto out;
969         }
970
971         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
972                 printf("inherited ACE present but should not!\n");
973                 ret = false;
974                 goto out;
975         }
976
977         if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
978                 printf("inherited trustee SID with flags 0x%02x not present!\n",
979                         ace_flags);
980                 ret = false;
981                 goto out;
982         }
983
984  out:
985         test_CloseKey(p, tctx, &new_handle);
986         test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
987         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
988
989         return ret;
990 }
991
992 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
993                                           struct torture_context *tctx,
994                                           struct policy_handle *handle,
995                                           const char *key)
996 {
997         bool ret = true;
998         int i;
999
1000         struct winreg_mask_result_table {
1001                 uint32_t access_mask;
1002                 WERROR open_werr;
1003                 WERROR get_werr;
1004                 WERROR set_werr;
1005         } sd_mask_tests[] = {
1006                 { 0,
1007                         WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1008                 { SEC_FLAG_MAXIMUM_ALLOWED,
1009                         WERR_OK, WERR_OK, WERR_OK },
1010                 { SEC_STD_WRITE_DAC,
1011                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1012                 { SEC_FLAG_SYSTEM_SECURITY,
1013                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1014         };
1015
1016         /* FIXME: before this test can ever run successfully we need a way to
1017          * correctly read a NULL security_descritpor in ndr, get the required
1018          * length, requery, etc.
1019          */
1020
1021         return true;
1022
1023         for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1024
1025                 torture_comment(tctx,
1026                                 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1027                                 sd_mask_tests[i].access_mask);
1028                 torture_comment(tctx,
1029                                 "expecting: open %s, get: %s, set: %s\n",
1030                                 win_errstr(sd_mask_tests[i].open_werr),
1031                                 win_errstr(sd_mask_tests[i].get_werr),
1032                                 win_errstr(sd_mask_tests[i].set_werr));
1033
1034                 if (_test_SecurityDescriptor(p, tctx, handle,
1035                                              sd_mask_tests[i].access_mask, key,
1036                                              sd_mask_tests[i].open_werr,
1037                                              sd_mask_tests[i].get_werr,
1038                                              sd_mask_tests[i].set_werr)) {
1039                         ret = false;
1040                 }
1041         }
1042
1043         return ret;
1044 }
1045
1046 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1047                                   struct torture_context *,
1048                                   struct policy_handle *,
1049                                   const char *,
1050                                   const struct dom_sid *);
1051
1052 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1053                                                struct torture_context *tctx,
1054                                                struct policy_handle *handle,
1055                                                const char *key,
1056                                                const char *test,
1057                                                uint32_t access_mask,
1058                                                uint32_t sec_info,
1059                                                struct security_descriptor *sd,
1060                                                WERROR set_werr,
1061                                                bool expect_present,
1062                                                bool (*fn) (struct dcerpc_pipe *,
1063                                                            struct torture_context *,
1064                                                            struct policy_handle *,
1065                                                            const char *,
1066                                                            const struct dom_sid *),
1067                                                const struct dom_sid *sid)
1068 {
1069         struct policy_handle new_handle;
1070         bool open_success = false;
1071
1072         torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1073                         "0x%08x, access_mask: 0x%08x\n",
1074                         test, sec_info, access_mask);
1075
1076         if (!_test_OpenKey(p, tctx, handle, key,
1077                            access_mask,
1078                            &new_handle,
1079                            WERR_OK,
1080                            &open_success)) {
1081                 return false;
1082         }
1083
1084         if (!open_success) {
1085                 printf("key did not open\n");
1086                 test_CloseKey(p, tctx, &new_handle);
1087                 return false;
1088         }
1089
1090         if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1091                                   sd,
1092                                   set_werr)) {
1093                 torture_warning(tctx,
1094                                 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1095                                 sec_info);
1096                 smb_panic("");
1097                 test_CloseKey(p, tctx, &new_handle);
1098                 return false;
1099         }
1100
1101         test_CloseKey(p, tctx, &new_handle);
1102
1103         if (W_ERROR_IS_OK(set_werr)) {
1104                 bool present;
1105                 present = fn(p, tctx, handle, key, sid);
1106                 if ((expect_present) && (!present)) {
1107                         torture_warning(tctx,
1108                                         "%s sid is not present!\n",
1109                                         test);
1110                         return false;
1111                 }
1112                 if ((!expect_present) && (present)) {
1113                         torture_warning(tctx,
1114                                         "%s sid is present but not expected!\n",
1115                                         test);
1116                         return false;
1117                 }
1118         }
1119
1120         return true;
1121 }
1122
1123 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1124                                             struct torture_context *tctx,
1125                                             struct policy_handle *handle,
1126                                             const char *key)
1127 {
1128         struct security_descriptor *sd_orig = NULL;
1129         struct dom_sid *sid = NULL;
1130         bool ret = true;
1131         int i, a;
1132
1133         struct security_descriptor *sd_owner =
1134                 security_descriptor_dacl_create(tctx,
1135                                                 0,
1136                                                 TEST_SID, NULL, NULL);
1137
1138         struct security_descriptor *sd_group =
1139                 security_descriptor_dacl_create(tctx,
1140                                                 0,
1141                                                 NULL, TEST_SID, NULL);
1142
1143         struct security_descriptor *sd_dacl =
1144                 security_descriptor_dacl_create(tctx,
1145                                                 0,
1146                                                 NULL, NULL,
1147                                                 TEST_SID,
1148                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1149                                                 SEC_GENERIC_ALL,
1150                                                 0,
1151                                                 SID_NT_AUTHENTICATED_USERS,
1152                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1153                                                 SEC_GENERIC_ALL,
1154                                                 0,
1155                                                 NULL);
1156
1157         struct security_descriptor *sd_sacl =
1158                 security_descriptor_sacl_create(tctx,
1159                                                 0,
1160                                                 NULL, NULL,
1161                                                 TEST_SID,
1162                                                 SEC_ACE_TYPE_SYSTEM_AUDIT,
1163                                                 SEC_GENERIC_ALL,
1164                                                 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1165                                                 NULL);
1166
1167         struct winreg_secinfo_table {
1168                 struct security_descriptor *sd;
1169                 uint32_t sec_info;
1170                 WERROR set_werr;
1171                 bool sid_present;
1172                 secinfo_verify_fn fn;
1173         };
1174
1175         struct winreg_secinfo_table sec_info_owner_tests[] = {
1176                 { sd_owner, 0, WERR_OK,
1177                         false, (secinfo_verify_fn)_test_owner_present },
1178                 { sd_owner, SECINFO_OWNER, WERR_OK,
1179                         true, (secinfo_verify_fn)_test_owner_present },
1180                 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1181                 { sd_owner, SECINFO_DACL, WERR_OK,
1182                         true, (secinfo_verify_fn)_test_owner_present },
1183                 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1184         };
1185
1186         uint32_t sd_owner_good_access_masks[] = {
1187                 SEC_FLAG_MAXIMUM_ALLOWED,
1188                 /* SEC_STD_WRITE_OWNER, */
1189         };
1190
1191         struct winreg_secinfo_table sec_info_group_tests[] = {
1192                 { sd_group, 0, WERR_OK,
1193                         false, (secinfo_verify_fn)_test_group_present },
1194                 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1195                 { sd_group, SECINFO_GROUP, WERR_OK,
1196                         true, (secinfo_verify_fn)_test_group_present },
1197                 { sd_group, SECINFO_DACL, WERR_OK,
1198                         true, (secinfo_verify_fn)_test_group_present },
1199                 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1200         };
1201
1202         uint32_t sd_group_good_access_masks[] = {
1203                 SEC_FLAG_MAXIMUM_ALLOWED,
1204         };
1205
1206         struct winreg_secinfo_table sec_info_dacl_tests[] = {
1207                 { sd_dacl, 0, WERR_OK,
1208                         false, (secinfo_verify_fn)_test_dacl_trustee_present },
1209                 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1210                 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1211                 { sd_dacl, SECINFO_DACL, WERR_OK,
1212                         true, (secinfo_verify_fn)_test_dacl_trustee_present },
1213                 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1214         };
1215
1216         uint32_t sd_dacl_good_access_masks[] = {
1217                 SEC_FLAG_MAXIMUM_ALLOWED,
1218                 SEC_STD_WRITE_DAC,
1219         };
1220
1221         struct winreg_secinfo_table sec_info_sacl_tests[] = {
1222                 { sd_sacl, 0, WERR_OK,
1223                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1224                 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1225                 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1226                 { sd_sacl, SECINFO_DACL, WERR_OK,
1227                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1228                 { sd_sacl, SECINFO_SACL, WERR_OK,
1229                         true, (secinfo_verify_fn)_test_sacl_trustee_present },
1230         };
1231
1232         uint32_t sd_sacl_good_access_masks[] = {
1233                 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1234                 /* SEC_FLAG_SYSTEM_SECURITY, */
1235         };
1236
1237         sid = dom_sid_parse_talloc(tctx, TEST_SID);
1238         if (sid == NULL) {
1239                 return false;
1240         }
1241
1242         if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1243                 return false;
1244         }
1245
1246         /* OWNER */
1247
1248         for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1249
1250                 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1251
1252                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1253                                         key,
1254                                         "OWNER",
1255                                         sd_owner_good_access_masks[a],
1256                                         sec_info_owner_tests[i].sec_info,
1257                                         sec_info_owner_tests[i].sd,
1258                                         sec_info_owner_tests[i].set_werr,
1259                                         sec_info_owner_tests[i].sid_present,
1260                                         sec_info_owner_tests[i].fn,
1261                                         sid))
1262                         {
1263                                 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1264                                 ret = false;
1265                                 goto out;
1266                         }
1267                 }
1268         }
1269
1270         /* GROUP */
1271
1272         for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1273
1274                 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1275
1276                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1277                                         key,
1278                                         "GROUP",
1279                                         sd_group_good_access_masks[a],
1280                                         sec_info_group_tests[i].sec_info,
1281                                         sec_info_group_tests[i].sd,
1282                                         sec_info_group_tests[i].set_werr,
1283                                         sec_info_group_tests[i].sid_present,
1284                                         sec_info_group_tests[i].fn,
1285                                         sid))
1286                         {
1287                                 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1288                                 ret = false;
1289                                 goto out;
1290                         }
1291                 }
1292         }
1293
1294         /* DACL */
1295
1296         for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1297
1298                 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1299
1300                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1301                                         key,
1302                                         "DACL",
1303                                         sd_dacl_good_access_masks[a],
1304                                         sec_info_dacl_tests[i].sec_info,
1305                                         sec_info_dacl_tests[i].sd,
1306                                         sec_info_dacl_tests[i].set_werr,
1307                                         sec_info_dacl_tests[i].sid_present,
1308                                         sec_info_dacl_tests[i].fn,
1309                                         sid))
1310                         {
1311                                 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1312                                 ret = false;
1313                                 goto out;
1314                         }
1315                 }
1316         }
1317
1318         /* SACL */
1319
1320         for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1321
1322                 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1323
1324                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1325                                         key,
1326                                         "SACL",
1327                                         sd_sacl_good_access_masks[a],
1328                                         sec_info_sacl_tests[i].sec_info,
1329                                         sec_info_sacl_tests[i].sd,
1330                                         sec_info_sacl_tests[i].set_werr,
1331                                         sec_info_sacl_tests[i].sid_present,
1332                                         sec_info_sacl_tests[i].fn,
1333                                         sid))
1334                         {
1335                                 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1336                                 ret = false;
1337                                 goto out;
1338                         }
1339                 }
1340         }
1341
1342  out:
1343         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1344
1345         return ret;
1346 }
1347
1348 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1349                                      struct torture_context *tctx,
1350                                      struct policy_handle *handle,
1351                                      const char *key)
1352 {
1353         bool ret = true;
1354
1355         if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1356                 printf("test_SecurityDescriptor failed\n");
1357                 ret = false;
1358         }
1359
1360         if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1361                 printf("test_SecurityDescriptorInheritance failed\n");
1362                 ret = false;
1363         }
1364
1365         if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1366                 printf("test_SecurityDescriptorBlockInheritance failed\n");
1367                 ret = false;
1368         }
1369
1370         if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1371                 printf("test_SecurityDescriptorsSecInfo failed\n");
1372                 ret = false;
1373         }
1374
1375         if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1376                 printf("test_SecurityDescriptorsMasks failed\n");
1377                 ret = false;
1378         }
1379
1380         return ret;
1381 }
1382
1383 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1384                            struct policy_handle *handle, const char *key)
1385 {
1386         NTSTATUS status;
1387         struct winreg_DeleteKey r;
1388
1389         r.in.handle = handle;
1390         init_winreg_String(&r.in.key, key);
1391
1392         status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1393
1394         torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1395         torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1396
1397         return true;
1398 }
1399
1400 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1401                               struct torture_context *tctx,
1402                               struct policy_handle *handle, char *kclass)
1403 {
1404         struct winreg_QueryInfoKey r;
1405         uint32_t num_subkeys, max_subkeylen, max_classlen,
1406                 num_values, max_valnamelen, max_valbufsize,
1407                 secdescsize;
1408         NTTIME last_changed_time;
1409
1410         ZERO_STRUCT(r);
1411         r.in.handle = handle;
1412         r.out.num_subkeys = &num_subkeys;
1413         r.out.max_subkeylen = &max_subkeylen;
1414         r.out.max_classlen = &max_classlen;
1415         r.out.num_values = &num_values;
1416         r.out.max_valnamelen = &max_valnamelen;
1417         r.out.max_valbufsize = &max_valbufsize;
1418         r.out.secdescsize = &secdescsize;
1419         r.out.last_changed_time = &last_changed_time;
1420
1421         r.out.classname = talloc(tctx, struct winreg_String);
1422
1423         r.in.classname = talloc(tctx, struct winreg_String);
1424         init_winreg_String(r.in.classname, kclass);
1425
1426         torture_assert_ntstatus_ok(tctx,
1427                                    dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1428                                    "QueryInfoKey failed");
1429
1430         torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1431
1432         return true;
1433 }
1434
1435 static bool test_SetValue(struct dcerpc_pipe *p,
1436                           struct torture_context *tctx,
1437                           struct policy_handle *handle,
1438                           const char *value_name,
1439                           enum winreg_Type type,
1440                           uint8_t *data,
1441                           uint32_t size)
1442 {
1443         struct winreg_SetValue r;
1444         struct winreg_String name;
1445
1446         torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1447                 value_name, str_regtype(type), size);
1448
1449         init_winreg_String(&name, value_name);
1450
1451         r.in.handle = handle;
1452         r.in.name = name;
1453         r.in.type = type;
1454         r.in.data = data;
1455         r.in.size = size;
1456
1457         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue(p, tctx, &r),
1458                 "winreg_SetValue failed");
1459         torture_assert_werr_ok(tctx, r.out.result,
1460                 "winreg_SetValue failed");
1461
1462         return true;
1463 }
1464
1465 static bool test_DeleteValue(struct dcerpc_pipe *p,
1466                              struct torture_context *tctx,
1467                              struct policy_handle *handle,
1468                              const char *value_name)
1469 {
1470         struct winreg_DeleteValue r;
1471         struct winreg_String value;
1472
1473         torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1474
1475         init_winreg_String(&value, value_name);
1476
1477         r.in.handle = handle;
1478         r.in.value = value;
1479
1480         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue(p, tctx, &r),
1481                 "winreg_DeleteValue failed");
1482         torture_assert_werr_ok(tctx, r.out.result,
1483                 "winreg_DeleteValue failed");
1484
1485         return true;
1486 }
1487
1488 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1489                      struct policy_handle *handle, int depth,
1490                      bool test_security);
1491
1492 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1493                          struct policy_handle *handle, int depth,
1494                          bool test_security)
1495 {
1496         struct winreg_EnumKey r;
1497         struct winreg_StringBuf kclass, name;
1498         NTSTATUS status;
1499         NTTIME t = 0;
1500
1501         kclass.name   = "";
1502         kclass.size   = 1024;
1503
1504         ZERO_STRUCT(r);
1505         r.in.handle = handle;
1506         r.in.enum_index = 0;
1507         r.in.name = &name;
1508         r.in.keyclass = &kclass;
1509         r.out.name = &name;
1510         r.in.last_changed_time = &t;
1511
1512         do {
1513                 name.name   = NULL;
1514                 name.size   = 1024;
1515
1516                 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1517
1518                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1519                         struct policy_handle key_handle;
1520
1521                         torture_comment(tctx, "EnumKey: %d: %s\n",
1522                                         r.in.enum_index,
1523                                         r.out.name->name);
1524
1525                         if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1526                                           &key_handle)) {
1527                         } else {
1528                                 test_key(p, tctx, &key_handle,
1529                                          depth + 1, test_security);
1530                         }
1531                 }
1532
1533                 r.in.enum_index++;
1534
1535         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1536
1537         torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1538
1539         if (!W_ERROR_IS_OK(r.out.result) &&
1540                 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1541                 torture_fail(tctx, "EnumKey failed");
1542         }
1543
1544         return true;
1545 }
1546
1547 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1548                                      struct torture_context *tctx,
1549                                      struct policy_handle *handle,
1550                                      const char *valuename)
1551 {
1552         struct winreg_QueryMultipleValues r;
1553         NTSTATUS status;
1554         uint32_t bufsize=0;
1555
1556         ZERO_STRUCT(r);
1557         r.in.key_handle = handle;
1558         r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1559         r.in.values[0].name = talloc(tctx, struct winreg_String);
1560         r.in.values[0].name->name = valuename;
1561         r.in.values[0].offset = 0;
1562         r.in.values[0].length = 0;
1563         r.in.values[0].type = 0;
1564
1565         r.in.num_values = 1;
1566         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1567         *r.in.buffer_size = bufsize;
1568         do {
1569                 *r.in.buffer_size = bufsize;
1570                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1571                                                                *r.in.buffer_size);
1572
1573                 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1574
1575                 if(NT_STATUS_IS_ERR(status))
1576                         torture_fail(tctx, "QueryMultipleValues failed");
1577
1578                 talloc_free(r.in.buffer);
1579                 bufsize += 0x20;
1580         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1581
1582         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1583
1584         return true;
1585 }
1586
1587 static bool test_QueryValue(struct dcerpc_pipe *p,
1588                             struct torture_context *tctx,
1589                             struct policy_handle *handle,
1590                             const char *valuename)
1591 {
1592         struct winreg_QueryValue r;
1593         NTSTATUS status;
1594         enum winreg_Type zero_type = 0;
1595         uint32_t offered = 0xfff;
1596         uint32_t zero = 0;
1597
1598         ZERO_STRUCT(r);
1599         r.in.handle = handle;
1600         r.in.data = NULL;
1601         r.in.value_name = talloc_zero(tctx, struct winreg_String);
1602         r.in.value_name->name = valuename;
1603         r.in.type = &zero_type;
1604         r.in.data_size = &offered;
1605         r.in.data_length = &zero;
1606
1607         status = dcerpc_winreg_QueryValue(p, tctx, &r);
1608         if (NT_STATUS_IS_ERR(status)) {
1609                 torture_fail(tctx, "QueryValue failed");
1610         }
1611
1612         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1613
1614         return true;
1615 }
1616
1617 static bool test_QueryValue_full(struct dcerpc_pipe *p,
1618                                  struct torture_context *tctx,
1619                                  struct policy_handle *handle,
1620                                  const char *valuename,
1621                                  bool existing_value)
1622 {
1623         struct winreg_QueryValue r;
1624         struct winreg_String value_name;
1625         enum winreg_Type type = REG_NONE;
1626         uint32_t data_size = 0;
1627         uint32_t real_data_size = 0;
1628         uint32_t data_length = 0;
1629         uint8_t *data = NULL;
1630         WERROR expected_error = WERR_BADFILE;
1631
1632         if (valuename == NULL) {
1633                 expected_error = WERR_INVALID_PARAM;
1634         }
1635
1636         ZERO_STRUCT(r);
1637
1638         init_winreg_String(&value_name, NULL);
1639
1640         torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1641
1642         r.in.handle = handle;
1643         r.in.value_name = &value_name;
1644
1645         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r), "QueryValue failed");
1646         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1647                 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1648
1649         init_winreg_String(&value_name, valuename);
1650         r.in.value_name = &value_name;
1651
1652         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1653                 "QueryValue failed");
1654         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1655                 "QueryValue failed");
1656
1657         r.in.type = &type;
1658         r.out.type = &type;
1659         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1660                 "QueryValue failed");
1661         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1662                 "QueryValue failed");
1663
1664         r.in.data_length = &data_length;
1665         r.out.data_length = &data_length;
1666         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1667                 "QueryValue failed");
1668         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1669                 "QueryValue failed");
1670
1671         r.in.data_size = &data_size;
1672         r.out.data_size = &data_size;
1673         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1674                 "QueryValue failed");
1675         if (existing_value) {
1676                 torture_assert_werr_ok(tctx, r.out.result,
1677                         "QueryValue failed");
1678         } else {
1679                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1680                         "QueryValue failed");
1681         }
1682
1683         real_data_size = *r.out.data_size;
1684
1685         data = talloc_zero_array(tctx, uint8_t, 0);
1686         r.in.data = data;
1687         r.out.data = data;
1688         *r.in.data_size = 0;
1689         *r.out.data_size = 0;
1690         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1691                 "QueryValue failed");
1692         if (existing_value) {
1693                 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1694                         "QueryValue failed");
1695         } else {
1696                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1697                         "QueryValue failed");
1698         }
1699
1700         data = talloc_zero_array(tctx, uint8_t, real_data_size);
1701         r.in.data = data;
1702         r.out.data = data;
1703         r.in.data_size = &real_data_size;
1704         r.out.data_size = &real_data_size;
1705         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1706                 "QueryValue failed");
1707         if (existing_value) {
1708                 torture_assert_werr_ok(tctx, r.out.result,
1709                         "QueryValue failed");
1710         } else {
1711                 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1712                         "QueryValue failed");
1713         }
1714
1715         return true;
1716 }
1717
1718 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1719                            struct policy_handle *handle, int max_valnamelen,
1720                            int max_valbufsize)
1721 {
1722         struct winreg_EnumValue r;
1723         enum winreg_Type type = 0;
1724         uint32_t size = max_valbufsize, zero = 0;
1725         bool ret = true;
1726         uint8_t buf8;
1727         struct winreg_ValNameBuf name;
1728
1729         name.name   = "";
1730         name.size   = 1024;
1731
1732         ZERO_STRUCT(r);
1733         r.in.handle = handle;
1734         r.in.enum_index = 0;
1735         r.in.name = &name;
1736         r.out.name = &name;
1737         r.in.type = &type;
1738         r.in.value = &buf8;
1739         r.in.length = &zero;
1740         r.in.size = &size;
1741
1742         do {
1743                 torture_assert_ntstatus_ok(tctx,
1744                                            dcerpc_winreg_EnumValue(p, tctx, &r),
1745                                            "EnumValue failed");
1746
1747                 if (W_ERROR_IS_OK(r.out.result)) {
1748                         ret &= test_QueryValue(p, tctx, handle,
1749                                                r.out.name->name);
1750                         ret &= test_QueryMultipleValues(p, tctx, handle,
1751                                                         r.out.name->name);
1752                 }
1753
1754                 r.in.enum_index++;
1755         } while (W_ERROR_IS_OK(r.out.result));
1756
1757         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1758                                   "EnumValue failed");
1759
1760         return ret;
1761 }
1762
1763 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1764                                      struct torture_context *tctx)
1765 {
1766         struct winreg_AbortSystemShutdown r;
1767         uint16_t server = 0x0;
1768
1769         ZERO_STRUCT(r);
1770         r.in.server = &server;
1771
1772         torture_assert_ntstatus_ok(tctx,
1773                                    dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1774                                    "AbortSystemShutdown failed");
1775
1776         torture_assert_werr_ok(tctx, r.out.result,
1777                                "AbortSystemShutdown failed");
1778
1779         return true;
1780 }
1781
1782 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1783                                         struct dcerpc_pipe *p)
1784 {
1785         struct winreg_InitiateSystemShutdown r;
1786         uint16_t hostname = 0x0;
1787
1788         ZERO_STRUCT(r);
1789         r.in.hostname = &hostname;
1790         r.in.message = talloc(tctx, struct lsa_StringLarge);
1791         init_lsa_StringLarge(r.in.message, "spottyfood");
1792         r.in.force_apps = 1;
1793         r.in.timeout = 30;
1794         r.in.do_reboot = 1;
1795
1796         torture_assert_ntstatus_ok(tctx,
1797                                    dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1798                                    "InitiateSystemShutdown failed");
1799
1800         torture_assert_werr_ok(tctx, r.out.result,
1801                                "InitiateSystemShutdown failed");
1802
1803         return test_AbortSystemShutdown(p, tctx);
1804 }
1805
1806
1807 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1808                                           struct dcerpc_pipe *p)
1809 {
1810         struct winreg_InitiateSystemShutdownEx r;
1811         uint16_t hostname = 0x0;
1812
1813         ZERO_STRUCT(r);
1814         r.in.hostname = &hostname;
1815         r.in.message = talloc(tctx, struct lsa_StringLarge);
1816         init_lsa_StringLarge(r.in.message, "spottyfood");
1817         r.in.force_apps = 1;
1818         r.in.timeout = 30;
1819         r.in.do_reboot = 1;
1820         r.in.reason = 0;
1821
1822         torture_assert_ntstatus_ok(tctx,
1823                 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1824                 "InitiateSystemShutdownEx failed");
1825
1826         torture_assert_werr_ok(tctx, r.out.result,
1827                                "InitiateSystemShutdownEx failed");
1828
1829         return test_AbortSystemShutdown(p, tctx);
1830 }
1831 #define MAX_DEPTH 2             /* Only go this far down the tree */
1832
1833 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1834                      struct policy_handle *handle, int depth,
1835                      bool test_security)
1836 {
1837         if (depth == MAX_DEPTH)
1838                 return true;
1839
1840         if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1841         }
1842
1843         if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1844         }
1845
1846         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1847         }
1848
1849         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1850         }
1851
1852         if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1853         }
1854
1855         test_CloseKey(p, tctx, handle);
1856
1857         return true;
1858 }
1859
1860 static bool test_SetValue_simple(struct dcerpc_pipe *p,
1861                                  struct torture_context *tctx,
1862                                  struct policy_handle *handle)
1863 {
1864         const char *value_name = TEST_VALUE;
1865         uint32_t value = 0x12345678;
1866         const char *string = "torture";
1867         DATA_BLOB blob;
1868         enum winreg_Type types[] = {
1869                 REG_DWORD,
1870                 REG_BINARY,
1871                 REG_SZ,
1872                 REG_MULTI_SZ
1873         };
1874         int t;
1875
1876         torture_comment(tctx, "Testing SetValue (standard formats)\n");
1877
1878         for (t=0; t < ARRAY_SIZE(types); t++) {
1879
1880                 enum winreg_Type w_type;
1881                 uint32_t w_size, w_length;
1882                 uint8_t *w_data;
1883
1884                 switch (types[t]) {
1885                 case REG_DWORD:
1886                         blob = data_blob_talloc_zero(tctx, 4);
1887                         SIVAL(blob.data, 0, value);
1888                         break;
1889                 case REG_BINARY:
1890                         blob = data_blob_string_const("binary_blob");
1891                         break;
1892                 case REG_SZ:
1893                         torture_assert(tctx,
1894                                 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1895                                                                   CH_UNIX, CH_UTF16,
1896                                                                   string,
1897                                                                   strlen(string)+1,
1898                                                                   (void **)&blob.data,
1899                                                                   &blob.length,
1900                                                                   false), "");
1901                         break;
1902                 case REG_MULTI_SZ:
1903                         torture_assert(tctx,
1904                                 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1905                                                                   CH_UNIX, CH_UTF16,
1906                                                                   string,
1907                                                                   strlen(string)+1,
1908                                                                   (void **)&blob.data,
1909                                                                   &blob.length,
1910                                                                   false), "");
1911                         torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1912                         memset(&blob.data[blob.length - 2], '\0', 2);
1913                         break;
1914                 default:
1915                         break;
1916                 }
1917
1918                 torture_assert(tctx,
1919                         test_SetValue(p, tctx, handle, value_name, types[t], blob.data, blob.length),
1920                         "test_SetValue failed");
1921                 torture_assert(tctx,
1922                         test_QueryValue_full(p, tctx, handle, value_name, true),
1923                         talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1924                 torture_assert(tctx,
1925                         test_winreg_QueryValue(tctx, p, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1926                         "test_winreg_QueryValue failed");
1927                 torture_assert(tctx,
1928                         test_DeleteValue(p, tctx, handle, value_name),
1929                         "test_DeleteValue failed");
1930
1931                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1932                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1933                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1934                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1935         }
1936
1937         torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
1938
1939         return true;
1940 }
1941
1942 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1943
1944 static bool test_Open_Security(struct torture_context *tctx,
1945                                struct dcerpc_pipe *p, void *userdata)
1946 {
1947         struct policy_handle handle, newhandle;
1948         bool ret = true, created2 = false;
1949         bool created4 = false;
1950         struct winreg_OpenHKLM r;
1951
1952         winreg_open_fn open_fn = userdata;
1953
1954         ZERO_STRUCT(r);
1955         r.in.system_name = 0;
1956         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1957         r.out.handle = &handle;
1958
1959         torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1960                                    "open");
1961
1962         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1963
1964         if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1965                 torture_comment(tctx,
1966                                 "CreateKey (TEST_KEY_BASE) failed\n");
1967         }
1968
1969         if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1970                               NULL, &newhandle)) {
1971                 created2 = true;
1972         }
1973
1974         if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1975                 printf("CloseKey failed\n");
1976                 ret = false;
1977         }
1978
1979         if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1980                 created4 = true;
1981         }
1982
1983         if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1984                 printf("CloseKey failed\n");
1985                 ret = false;
1986         }
1987
1988         if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1989                 ret = false;
1990         }
1991
1992         if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1993                 printf("DeleteKey failed\n");
1994                 ret = false;
1995         }
1996
1997         if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1998                 printf("DeleteKey failed\n");
1999                 ret = false;
2000         }
2001
2002         /* The HKCR hive has a very large fanout */
2003         if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
2004                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
2005                         ret = false;
2006                 }
2007         } else {
2008                 if (!test_key(p, tctx, &handle, 0, true)) {
2009                         ret = false;
2010                 }
2011         }
2012
2013         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2014
2015         return ret;
2016 }
2017
2018 static bool test_SetValue_extended(struct dcerpc_pipe *p,
2019                                    struct torture_context *tctx,
2020                                    struct policy_handle *handle)
2021 {
2022         const char *value_name = TEST_VALUE;
2023         enum winreg_Type types[] = {
2024                 REG_NONE,
2025                 REG_SZ,
2026                 REG_EXPAND_SZ,
2027                 REG_BINARY,
2028                 REG_DWORD,
2029                 REG_DWORD_BIG_ENDIAN,
2030                 REG_LINK,
2031                 REG_MULTI_SZ,
2032                 REG_RESOURCE_LIST,
2033                 REG_FULL_RESOURCE_DESCRIPTOR,
2034                 REG_RESOURCE_REQUIREMENTS_LIST,
2035                 REG_QWORD,
2036                 12,
2037                 13,
2038                 14,
2039                 55,
2040                 123456,
2041                 653210
2042         };
2043         const char *str = "abcdefghijklmnopqrstuvwxzy";
2044         int t, s;
2045
2046         if (torture_setting_bool(tctx, "samba3", false) ||
2047             torture_setting_bool(tctx, "samba4", false)) {
2048                 torture_skip(tctx, "skipping extended SetValue test against Samba");
2049         }
2050
2051         torture_comment(tctx, "Testing SetValue (extended formats)\n");
2052
2053         for (t=0; t < ARRAY_SIZE(types); t++) {
2054         for (s=0; s < strlen(str); s++) {
2055
2056                 enum winreg_Type w_type;
2057                 uint32_t w_size, w_length;
2058                 uint8_t *w_data;
2059
2060                 const char *string = talloc_strndup(tctx, str, s);
2061                 DATA_BLOB blob = data_blob_string_const(string);
2062
2063                 torture_assert(tctx,
2064                         test_SetValue(p, tctx, handle, value_name, types[t], blob.data, blob.length),
2065                         "test_SetValue failed");
2066
2067                 torture_assert(tctx,
2068                         test_winreg_QueryValue(tctx, p, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2069                         "test_winreg_QueryValue failed");
2070
2071                 torture_assert(tctx,
2072                         test_DeleteValue(p, tctx, handle, value_name),
2073                         "test_DeleteValue failed");
2074
2075                 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2076                 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2077                 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2078                 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2079         }
2080         }
2081
2082         torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2083
2084         return true;
2085 }
2086
2087 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2088 #define VALUE_CURRENT_VERSION "CurrentVersion"
2089
2090 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2091                       void *userdata)
2092 {
2093         struct policy_handle handle, newhandle;
2094         bool ret = true, created = false, deleted = false;
2095         bool created3 = false, created_subkey = false;
2096         struct winreg_OpenHKLM r;
2097
2098         winreg_open_fn open_fn = userdata;
2099
2100         ZERO_STRUCT(r);
2101         r.in.system_name = 0;
2102         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2103         r.out.handle = &handle;
2104
2105         torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
2106                                    "open");
2107
2108         if (open_fn == (void *)dcerpc_winreg_OpenHKLM) {
2109 #if 0
2110                 torture_assert(tctx, test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, &newhandle),
2111                         "failed to open current version key");
2112 #else
2113                 torture_assert(tctx, _test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, KEY_QUERY_VALUE, &newhandle, WERR_OK, NULL),
2114                         "failed to open current version key");
2115 #endif
2116                 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2117                         "failed to query current version");
2118                 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, "IDoNotExist", false),
2119                         "failed to query current version");
2120                 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, NULL, false),
2121                         "test_QueryValue_full for NULL value failed");
2122                 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, "", false),
2123                         "test_QueryValue_full for \"\" value failed");
2124
2125                 torture_assert(tctx, test_CloseKey(p, tctx, &newhandle),
2126                         "failed to close current version key");
2127         }
2128
2129         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2130
2131         if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
2132                 torture_comment(tctx,
2133                                 "CreateKey (TEST_KEY_BASE) failed\n");
2134         }
2135
2136         if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
2137                 torture_comment(tctx,
2138                                 "CreateKey failed - not considering a failure\n");
2139         } else {
2140                 created = true;
2141         }
2142
2143         if (created && !test_FlushKey(p, tctx, &handle)) {
2144                 torture_comment(tctx, "FlushKey failed\n");
2145                 ret = false;
2146         }
2147
2148         if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
2149                 torture_fail(tctx,
2150                              "CreateKey failed (OpenKey after Create didn't work)\n");
2151
2152         if (created) {
2153                 torture_assert(tctx, test_SetValue_simple(p, tctx, &newhandle),
2154                         "simple SetValue test failed");
2155                 torture_assert(tctx, test_SetValue_extended(p, tctx, &newhandle),
2156                         "extended SetValue test failed");
2157         }
2158
2159         if (created && !test_CloseKey(p, tctx, &newhandle))
2160                 torture_fail(tctx,
2161                              "CreateKey failed (CloseKey after Open didn't work)\n");
2162
2163         if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
2164                 torture_comment(tctx, "DeleteKey failed\n");
2165                 ret = false;
2166         } else {
2167                 deleted = true;
2168         }
2169
2170         if (created && !test_FlushKey(p, tctx, &handle)) {
2171                 torture_comment(tctx, "FlushKey failed\n");
2172                 ret = false;
2173         }
2174
2175         if (created && deleted &&
2176             !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
2177                            SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
2178                            WERR_BADFILE, NULL)) {
2179                 torture_comment(tctx,
2180                                 "DeleteKey failed (OpenKey after Delete "
2181                                 "did not return WERR_BADFILE)\n");
2182                 ret = false;
2183         }
2184
2185         if (!test_GetVersion(p, tctx, &handle)) {
2186                 torture_comment(tctx, "GetVersion failed\n");
2187                 ret = false;
2188         }
2189
2190         if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
2191                 created3 = true;
2192         }
2193
2194         if (created3 &&
2195             test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
2196                 created_subkey = true;
2197         }
2198
2199         if (created_subkey &&
2200             !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
2201                 printf("DeleteKey failed\n");
2202                 ret = false;
2203         }
2204
2205         /* The HKCR hive has a very large fanout */
2206         if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
2207                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2208                         ret = false;
2209                 }
2210         } else {
2211                 if (!test_key(p, tctx, &handle, 0, false)) {
2212                         ret = false;
2213                 }
2214         }
2215
2216         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2217
2218         return ret;
2219 }
2220
2221 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2222 {
2223         struct torture_rpc_tcase *tcase;
2224         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2225         struct torture_test *test;
2226
2227         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2228                                                   &ndr_table_winreg);
2229
2230         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2231                                           test_InitiateSystemShutdown);
2232         test->dangerous = true;
2233
2234         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2235                                           test_InitiateSystemShutdownEx);
2236         test->dangerous = true;
2237
2238         /* Basic tests without security descriptors */
2239         torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
2240                                       test_Open,
2241                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2242         torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
2243                                       test_Open,
2244                                       (winreg_open_fn)dcerpc_winreg_OpenHKU);
2245         torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
2246                                       test_Open,
2247                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2248         torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
2249                                       test_Open,
2250                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU);
2251
2252         /* Security descriptor tests */
2253         torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
2254                                       test_Open_Security,
2255                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2256         torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
2257                                       test_Open_Security,
2258                                       (winreg_open_fn)dcerpc_winreg_OpenHKU);
2259         torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
2260                                       test_Open_Security,
2261                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2262         torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
2263                                       test_Open_Security,
2264                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU);
2265
2266         return suite;
2267 }