1 /*
2 Unix SMB/CIFS implementation.
3 test suite for winreg rpc operations
4
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Jelmer Vernooij 2004-2007
7 Copyright (C) Günther Deschner 2007,2010
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_winreg_c.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "libcli/security/security.h"
27 #include "torture/rpc/torture_rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
30
31 #define TEST_KEY_BASE "winreg_torture_test"
32 #define TEST_KEY1 "spottyfoot"
33 #define TEST_KEY2 "with a SD (#1)"
34 #define TEST_KEY3 "with a subkey"
35 #define TEST_KEY4 "sd_tests"
36 #define TEST_SUBKEY "subkey"
37 #define TEST_SUBKEY_SD "subkey_sd"
38 #define TEST_SUBSUBKEY_SD "subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
40 #define TEST_KEY_VOLATILE "torture_volatile_key"
41 #define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
42 #define TEST_KEY_SYMLINK "torture_symlink_key"
43 #define TEST_KEY_SYMLINK_DEST "torture_symlink_dest"
44
45 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
46
init_lsa_StringLarge(struct lsa_StringLarge * name,const char * s)47 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
48 {
49 name->string = s;
50 }
51
init_winreg_String(struct winreg_String * name,const char * s)52 static void init_winreg_String(struct winreg_String *name, const char *s)
53 {
54 name->name = s;
55 if (s) {
56 name->name_len = 2 * (strlen_m(s) + 1);
57 name->name_size = name->name_len;
58 } else {
59 name->name_len = 0;
60 name->name_size = 0;
61 }
62 }
63
test_GetVersion(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)64 static bool test_GetVersion(struct dcerpc_binding_handle *b,
65 struct torture_context *tctx,
66 struct policy_handle *handle)
67 {
68 struct winreg_GetVersion r;
69 uint32_t v;
70
71 torture_comment(tctx, "Testing GetVersion\n");
72
73 ZERO_STRUCT(r);
74 r.in.handle = handle;
75 r.out.version = &v;
76
77 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
78 "GetVersion failed");
79
80 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
81
82 return true;
83 }
84
test_NotifyChangeKeyValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)85 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
86 struct torture_context *tctx,
87 struct policy_handle *handle)
88 {
89 struct winreg_NotifyChangeKeyValue r;
90
91 ZERO_STRUCT(r);
92 r.in.handle = handle;
93 r.in.watch_subtree = true;
94 r.in.notify_filter = 0;
95 r.in.unknown = r.in.unknown2 = 0;
96 init_winreg_String(&r.in.string1, NULL);
97 init_winreg_String(&r.in.string2, NULL);
98
99 torture_assert_ntstatus_ok(tctx,
100 dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
101 "NotifyChangeKeyValue failed");
102
103 if (!W_ERROR_IS_OK(r.out.result)) {
104 torture_comment(tctx,
105 "NotifyChangeKeyValue failed - %s - not considering\n",
106 win_errstr(r.out.result));
107 return true;
108 }
109
110 return true;
111 }
112
test_CreateKey_opts(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * name,const char * kclass,uint32_t options,uint32_t access_mask,struct winreg_SecBuf * secdesc,WERROR expected_result,enum winreg_CreateAction * action_taken_p,struct policy_handle * new_handle_p)113 static bool test_CreateKey_opts(struct torture_context *tctx,
114 struct dcerpc_binding_handle *b,
115 struct policy_handle *handle,
116 const char *name,
117 const char *kclass,
118 uint32_t options,
119 uint32_t access_mask,
120 struct winreg_SecBuf *secdesc,
121 WERROR expected_result,
122 enum winreg_CreateAction *action_taken_p,
123 struct policy_handle *new_handle_p)
124 {
125 struct winreg_CreateKey r;
126 struct policy_handle newhandle;
127 enum winreg_CreateAction action_taken = 0;
128
129 torture_comment(tctx, "Testing CreateKey(%s)\n", name);
130
131 ZERO_STRUCT(r);
132 r.in.handle = handle;
133 init_winreg_String(&r.in.name, name);
134 init_winreg_String(&r.in.keyclass, kclass);
135 r.in.options = options;
136 r.in.access_mask = access_mask;
137 r.in.action_taken = &action_taken;
138 r.in.secdesc = secdesc;
139 r.out.new_handle = &newhandle;
140 r.out.action_taken = &action_taken;
141
142 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
143 "CreateKey failed");
144
145 torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
146
147 if (new_handle_p) {
148 *new_handle_p = newhandle;
149 }
150 if (action_taken_p) {
151 *action_taken_p = *r.out.action_taken;
152 }
153
154 return true;
155 }
156
test_CreateKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * name,const char * kclass)157 static bool test_CreateKey(struct dcerpc_binding_handle *b,
158 struct torture_context *tctx,
159 struct policy_handle *handle, const char *name,
160 const char *kclass)
161 {
162 return test_CreateKey_opts(tctx, b, handle, name, kclass,
163 REG_OPTION_NON_VOLATILE,
164 SEC_FLAG_MAXIMUM_ALLOWED,
165 NULL, /* secdesc */
166 WERR_OK,
167 NULL, /* action_taken */
168 NULL /* new_handle */);
169 }
170
171 /*
172 createkey testing with a SD
173 */
test_CreateKey_sd(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * name,const char * kclass,struct policy_handle * newhandle)174 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
175 struct torture_context *tctx,
176 struct policy_handle *handle, const char *name,
177 const char *kclass,
178 struct policy_handle *newhandle)
179 {
180 struct winreg_CreateKey r;
181 enum winreg_CreateAction action_taken = 0;
182 struct security_descriptor *sd;
183 DATA_BLOB sdblob;
184 struct winreg_SecBuf secbuf;
185
186 sd = security_descriptor_dacl_create(tctx,
187 0,
188 NULL, NULL,
189 SID_NT_AUTHENTICATED_USERS,
190 SEC_ACE_TYPE_ACCESS_ALLOWED,
191 SEC_GENERIC_ALL,
192 SEC_ACE_FLAG_OBJECT_INHERIT |
193 SEC_ACE_FLAG_CONTAINER_INHERIT,
194 NULL);
195
196 torture_assert_ndr_success(tctx,
197 ndr_push_struct_blob(&sdblob, tctx, sd,
198 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
199 "Failed to push security_descriptor ?!\n");
200
201 secbuf.sd.data = sdblob.data;
202 secbuf.sd.len = sdblob.length;
203 secbuf.sd.size = sdblob.length;
204 secbuf.length = sdblob.length-10;
205 secbuf.inherit = 0;
206
207 ZERO_STRUCT(r);
208 r.in.handle = handle;
209 r.out.new_handle = newhandle;
210 init_winreg_String(&r.in.name, name);
211 init_winreg_String(&r.in.keyclass, kclass);
212 r.in.options = 0x0;
213 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214 r.in.action_taken = r.out.action_taken = &action_taken;
215 r.in.secdesc = &secbuf;
216
217 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
218 "CreateKey with sd failed");
219
220 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
221
222 return true;
223 }
224
_test_GetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,uint32_t * sec_info_ptr,WERROR get_werr,struct security_descriptor ** sd_out)225 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
226 struct torture_context *tctx,
227 struct policy_handle *handle,
228 uint32_t *sec_info_ptr,
229 WERROR get_werr,
230 struct security_descriptor **sd_out)
231 {
232 struct winreg_GetKeySecurity r;
233 struct security_descriptor *sd = NULL;
234 uint32_t sec_info;
235 DATA_BLOB sdblob;
236 struct dcerpc_binding_handle *b = p->binding_handle;
237
238 if (sec_info_ptr) {
239 sec_info = *sec_info_ptr;
240 } else {
241 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
242 }
243
244 ZERO_STRUCT(r);
245
246 r.in.handle = handle;
247 r.in.sec_info = sec_info;
248 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
249 r.in.sd->size = 0x1000;
250
251 torture_assert_ntstatus_ok(tctx,
252 dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
253 "GetKeySecurity failed");
254
255 torture_assert_werr_equal(tctx, r.out.result, get_werr,
256 "GetKeySecurity failed");
257
258 sdblob.data = r.out.sd->data;
259 sdblob.length = r.out.sd->len;
260
261 sd = talloc_zero(tctx, struct security_descriptor);
262
263 torture_assert_ndr_success(tctx,
264 ndr_pull_struct_blob(&sdblob, tctx, sd,
265 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
266 "pull_security_descriptor failed");
267
268 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
269 NDR_PRINT_DEBUG(security_descriptor, sd);
270 }
271
272 if (sd_out) {
273 *sd_out = sd;
274 } else {
275 talloc_free(sd);
276 }
277
278 return true;
279 }
280
test_GetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,struct security_descriptor ** sd_out)281 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
282 struct torture_context *tctx,
283 struct policy_handle *handle,
284 struct security_descriptor **sd_out)
285 {
286 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
287 }
288
_test_SetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,uint32_t * sec_info_ptr,struct security_descriptor * sd,WERROR werr)289 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
290 struct torture_context *tctx,
291 struct policy_handle *handle,
292 uint32_t *sec_info_ptr,
293 struct security_descriptor *sd,
294 WERROR werr)
295 {
296 struct winreg_SetKeySecurity r;
297 struct KeySecurityData *sdata = NULL;
298 DATA_BLOB sdblob;
299 uint32_t sec_info;
300 struct dcerpc_binding_handle *b = p->binding_handle;
301
302 ZERO_STRUCT(r);
303
304 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
305 NDR_PRINT_DEBUG(security_descriptor, sd);
306 }
307
308 torture_assert_ndr_success(tctx,
309 ndr_push_struct_blob(&sdblob, tctx, sd,
310 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
311 "push_security_descriptor failed");
312
313 sdata = talloc_zero(tctx, struct KeySecurityData);
314 sdata->data = sdblob.data;
315 sdata->size = sdblob.length;
316 sdata->len = sdblob.length;
317
318 if (sec_info_ptr) {
319 sec_info = *sec_info_ptr;
320 } else {
321 sec_info = SECINFO_UNPROTECTED_SACL |
322 SECINFO_UNPROTECTED_DACL;
323 if (sd->owner_sid) {
324 sec_info |= SECINFO_OWNER;
325 }
326 if (sd->group_sid) {
327 sec_info |= SECINFO_GROUP;
328 }
329 if (sd->sacl) {
330 sec_info |= SECINFO_SACL;
331 }
332 if (sd->dacl) {
333 sec_info |= SECINFO_DACL;
334 }
335 }
336
337 r.in.handle = handle;
338 r.in.sec_info = sec_info;
339 r.in.sd = sdata;
340
341 torture_assert_ntstatus_ok(tctx,
342 dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
343 "SetKeySecurity failed");
344
345 torture_assert_werr_equal(tctx, r.out.result, werr,
346 "SetKeySecurity failed");
347
348 return true;
349 }
350
test_SetKeySecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,struct security_descriptor * sd)351 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
352 struct torture_context *tctx,
353 struct policy_handle *handle,
354 struct security_descriptor *sd)
355 {
356 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
357 }
358
test_CloseKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)359 static bool test_CloseKey(struct dcerpc_binding_handle *b,
360 struct torture_context *tctx,
361 struct policy_handle *handle)
362 {
363 struct winreg_CloseKey r;
364
365 ZERO_STRUCT(r);
366 r.in.handle = r.out.handle = handle;
367
368 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
369 "CloseKey failed");
370
371 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
372
373 return true;
374 }
375
test_FlushKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)376 static bool test_FlushKey(struct dcerpc_binding_handle *b,
377 struct torture_context *tctx,
378 struct policy_handle *handle)
379 {
380 struct winreg_FlushKey r;
381
382 ZERO_STRUCT(r);
383 r.in.handle = handle;
384
385 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
386 "FlushKey failed");
387
388 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
389
390 return true;
391 }
392
test_OpenKey_opts(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * hive_handle,const char * keyname,uint32_t options,uint32_t access_mask,struct policy_handle * key_handle,WERROR expected_result)393 static bool test_OpenKey_opts(struct torture_context *tctx,
394 struct dcerpc_binding_handle *b,
395 struct policy_handle *hive_handle,
396 const char *keyname,
397 uint32_t options,
398 uint32_t access_mask,
399 struct policy_handle *key_handle,
400 WERROR expected_result)
401 {
402 struct winreg_OpenKey r;
403
404 ZERO_STRUCT(r);
405 r.in.parent_handle = hive_handle;
406 init_winreg_String(&r.in.keyname, keyname);
407 r.in.options = options;
408 r.in.access_mask = access_mask;
409 r.out.handle = key_handle;
410
411 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
412 "OpenKey failed");
413
414 torture_assert_werr_equal(tctx, r.out.result, expected_result,
415 "OpenKey failed");
416
417 return true;
418 }
419
test_OpenKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * hive_handle,const char * keyname,struct policy_handle * key_handle)420 static bool test_OpenKey(struct dcerpc_binding_handle *b,
421 struct torture_context *tctx,
422 struct policy_handle *hive_handle,
423 const char *keyname, struct policy_handle *key_handle)
424 {
425 return test_OpenKey_opts(tctx, b, hive_handle, keyname,
426 REG_OPTION_NON_VOLATILE,
427 SEC_FLAG_MAXIMUM_ALLOWED,
428 key_handle,
429 WERR_OK);
430 }
431
test_Cleanup(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * key)432 static bool test_Cleanup(struct dcerpc_binding_handle *b,
433 struct torture_context *tctx,
434 struct policy_handle *handle, const char *key)
435 {
436 struct winreg_DeleteKey r;
437
438 ZERO_STRUCT(r);
439 r.in.handle = handle;
440
441 init_winreg_String(&r.in.key, key);
442 dcerpc_winreg_DeleteKey_r(b, tctx, &r);
443
444 return true;
445 }
446
_test_GetSetSecurityDescriptor(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,WERROR get_werr,WERROR set_werr)447 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
448 struct torture_context *tctx,
449 struct policy_handle *handle,
450 WERROR get_werr,
451 WERROR set_werr)
452 {
453 struct security_descriptor *sd = NULL;
454
455 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
456 return false;
457 }
458
459 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
460 return false;
461 }
462
463 return true;
464 }
465
test_SecurityDescriptor(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)466 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
467 struct torture_context *tctx,
468 struct policy_handle *handle,
469 const char *key)
470 {
471 struct policy_handle new_handle;
472 bool ret = true;
473 struct dcerpc_binding_handle *b = p->binding_handle;
474
475 torture_comment(tctx, "SecurityDescriptor get & set\n");
476
477 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
478 return false;
479 }
480
481 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
482 WERR_OK, WERR_OK)) {
483 ret = false;
484 }
485
486 if (!test_CloseKey(b, tctx, &new_handle)) {
487 return false;
488 }
489
490 return ret;
491 }
492
_test_SecurityDescriptor(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,uint32_t access_mask,const char * key,WERROR open_werr,WERROR get_werr,WERROR set_werr)493 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
494 struct torture_context *tctx,
495 struct policy_handle *handle,
496 uint32_t access_mask,
497 const char *key,
498 WERROR open_werr,
499 WERROR get_werr,
500 WERROR set_werr)
501 {
502 struct policy_handle new_handle;
503 bool ret = true;
504 struct dcerpc_binding_handle *b = p->binding_handle;
505
506 torture_assert(tctx,
507 test_OpenKey_opts(tctx, b, handle, key,
508 REG_OPTION_NON_VOLATILE,
509 access_mask,
510 &new_handle,
511 open_werr),
512 "failed to open key");
513
514 if (!W_ERROR_IS_OK(open_werr)) {
515 return true;
516 }
517
518 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
519 get_werr, set_werr)) {
520 ret = false;
521 }
522
523 if (!test_CloseKey(b, tctx, &new_handle)) {
524 return false;
525 }
526
527 return ret;
528 }
529
test_dacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)530 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
531 struct torture_context *tctx,
532 struct policy_handle *handle,
533 const struct dom_sid *sid)
534 {
535 struct security_descriptor *sd = NULL;
536 int i;
537
538 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
539 return false;
540 }
541
542 if (!sd || !sd->dacl) {
543 return false;
544 }
545
546 for (i = 0; i < sd->dacl->num_aces; i++) {
547 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
548 return true;
549 }
550 }
551
552 return false;
553 }
554
_test_dacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)555 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
556 struct torture_context *tctx,
557 struct policy_handle *handle,
558 const char *key,
559 const struct dom_sid *sid)
560 {
561 struct policy_handle new_handle;
562 bool ret = true;
563 struct dcerpc_binding_handle *b = p->binding_handle;
564
565 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
566 return false;
567 }
568
569 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
570
571 test_CloseKey(b, tctx, &new_handle);
572
573 return ret;
574 }
575
test_sacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)576 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
577 struct torture_context *tctx,
578 struct policy_handle *handle,
579 const struct dom_sid *sid)
580 {
581 struct security_descriptor *sd = NULL;
582 int i;
583 uint32_t sec_info = SECINFO_SACL;
584
585 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
586 return false;
587 }
588
589 if (!sd || !sd->sacl) {
590 return false;
591 }
592
593 for (i = 0; i < sd->sacl->num_aces; i++) {
594 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
595 return true;
596 }
597 }
598
599 return false;
600 }
601
_test_sacl_trustee_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)602 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
603 struct torture_context *tctx,
604 struct policy_handle *handle,
605 const char *key,
606 const struct dom_sid *sid)
607 {
608 struct policy_handle new_handle;
609 bool ret = true;
610 struct dcerpc_binding_handle *b = p->binding_handle;
611
612 torture_assert(tctx,
613 test_OpenKey_opts(tctx, b, handle, key,
614 REG_OPTION_NON_VOLATILE,
615 SEC_FLAG_SYSTEM_SECURITY,
616 &new_handle,
617 WERR_OK),
618 "failed to open key");
619
620 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
621
622 test_CloseKey(b, tctx, &new_handle);
623
624 return ret;
625 }
626
test_owner_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)627 static bool test_owner_present(struct dcerpc_pipe *p,
628 struct torture_context *tctx,
629 struct policy_handle *handle,
630 const struct dom_sid *sid)
631 {
632 struct security_descriptor *sd = NULL;
633 uint32_t sec_info = SECINFO_OWNER;
634
635 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
636 return false;
637 }
638
639 if (!sd || !sd->owner_sid) {
640 return false;
641 }
642
643 return dom_sid_equal(sd->owner_sid, sid);
644 }
645
_test_owner_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)646 static bool _test_owner_present(struct dcerpc_pipe *p,
647 struct torture_context *tctx,
648 struct policy_handle *handle,
649 const char *key,
650 const struct dom_sid *sid)
651 {
652 struct policy_handle new_handle;
653 bool ret = true;
654 struct dcerpc_binding_handle *b = p->binding_handle;
655
656 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
657 return false;
658 }
659
660 ret = test_owner_present(p, tctx, &new_handle, sid);
661
662 test_CloseKey(b, tctx, &new_handle);
663
664 return ret;
665 }
666
test_group_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid)667 static bool test_group_present(struct dcerpc_pipe *p,
668 struct torture_context *tctx,
669 struct policy_handle *handle,
670 const struct dom_sid *sid)
671 {
672 struct security_descriptor *sd = NULL;
673 uint32_t sec_info = SECINFO_GROUP;
674
675 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
676 return false;
677 }
678
679 if (!sd || !sd->group_sid) {
680 return false;
681 }
682
683 return dom_sid_equal(sd->group_sid, sid);
684 }
685
_test_group_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const struct dom_sid * sid)686 static bool _test_group_present(struct dcerpc_pipe *p,
687 struct torture_context *tctx,
688 struct policy_handle *handle,
689 const char *key,
690 const struct dom_sid *sid)
691 {
692 struct policy_handle new_handle;
693 bool ret = true;
694 struct dcerpc_binding_handle *b = p->binding_handle;
695
696 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
697 return false;
698 }
699
700 ret = test_group_present(p, tctx, &new_handle, sid);
701
702 test_CloseKey(b, tctx, &new_handle);
703
704 return ret;
705 }
706
test_dacl_trustee_flags_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct dom_sid * sid,uint8_t flags)707 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
708 struct torture_context *tctx,
709 struct policy_handle *handle,
710 const struct dom_sid *sid,
711 uint8_t flags)
712 {
713 struct security_descriptor *sd = NULL;
714 int i;
715
716 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
717 return false;
718 }
719
720 if (!sd || !sd->dacl) {
721 return false;
722 }
723
724 for (i = 0; i < sd->dacl->num_aces; i++) {
725 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
726 (sd->dacl->aces[i].flags == flags)) {
727 return true;
728 }
729 }
730
731 return false;
732 }
733
test_dacl_ace_present(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const struct security_ace * ace)734 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
735 struct torture_context *tctx,
736 struct policy_handle *handle,
737 const struct security_ace *ace)
738 {
739 struct security_descriptor *sd = NULL;
740 int i;
741
742 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
743 return false;
744 }
745
746 if (!sd || !sd->dacl) {
747 return false;
748 }
749
750 for (i = 0; i < sd->dacl->num_aces; i++) {
751 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
752 return true;
753 }
754 }
755
756 return false;
757 }
758
test_RestoreSecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,struct security_descriptor * sd)759 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
760 struct torture_context *tctx,
761 struct policy_handle *handle,
762 const char *key,
763 struct security_descriptor *sd)
764 {
765 struct policy_handle new_handle;
766 bool ret = true;
767 struct dcerpc_binding_handle *b = p->binding_handle;
768
769 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
770 return false;
771 }
772
773 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
774 ret = false;
775 }
776
777 if (!test_CloseKey(b, tctx, &new_handle)) {
778 ret = false;
779 }
780
781 return ret;
782 }
783
test_BackupSecurity(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,struct security_descriptor ** sd)784 static bool test_BackupSecurity(struct dcerpc_pipe *p,
785 struct torture_context *tctx,
786 struct policy_handle *handle,
787 const char *key,
788 struct security_descriptor **sd)
789 {
790 struct policy_handle new_handle;
791 bool ret = true;
792 struct dcerpc_binding_handle *b = p->binding_handle;
793
794 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
795 return false;
796 }
797
798 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
799 ret = false;
800 }
801
802 if (!test_CloseKey(b, tctx, &new_handle)) {
803 ret = false;
804 }
805
806 return ret;
807 }
808
test_SecurityDescriptorInheritance(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)809 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
810 struct torture_context *tctx,
811 struct policy_handle *handle,
812 const char *key)
813 {
814 /* get sd
815 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
816 set sd
817 get sd
818 check ace
819 add subkey
820 get sd
821 check ace
822 add subsubkey
823 get sd
824 check ace
825 del subsubkey
826 del subkey
827 reset sd
828 */
829
830 struct security_descriptor *sd = NULL;
831 struct security_descriptor *sd_orig = NULL;
832 struct security_ace *ace = NULL;
833 struct policy_handle new_handle;
834 bool ret = true;
835 struct dcerpc_binding_handle *b = p->binding_handle;
836 const char *test_subkey_sd;
837 const char *test_subsubkey_sd;
838
839 torture_comment(tctx, "SecurityDescriptor inheritance\n");
840
841 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
842 return false;
843 }
844
845 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
846 return false;
847 }
848
849 sd_orig = security_descriptor_copy(tctx, sd);
850 if (sd_orig == NULL) {
851 return false;
852 }
853
854 ace = security_ace_create(tctx,
855 TEST_SID,
856 SEC_ACE_TYPE_ACCESS_ALLOWED,
857 SEC_STD_REQUIRED,
858 SEC_ACE_FLAG_CONTAINER_INHERIT);
859
860 torture_assert_ntstatus_ok(tctx,
861 security_descriptor_dacl_add(sd, ace),
862 "failed to add ace");
863
864 /* FIXME: add further tests for these flags */
865 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
866 SEC_DESC_SACL_AUTO_INHERITED;
867
868 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
869 return false;
870 }
871
872 torture_assert(tctx,
873 test_dacl_ace_present(p, tctx, &new_handle, ace),
874 "new ACE not present!");
875
876 if (!test_CloseKey(b, tctx, &new_handle)) {
877 return false;
878 }
879
880 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
881
882 if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
883 ret = false;
884 goto out;
885 }
886
887 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
888 ret = false;
889 goto out;
890 }
891
892 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
893 torture_comment(tctx, "inherited ACE not present!\n");
894 ret = false;
895 goto out;
896 }
897
898 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
899
900 test_CloseKey(b, tctx, &new_handle);
901 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
902 ret = false;
903 goto out;
904 }
905
906 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
907 ret = false;
908 goto out;
909 }
910
911 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
912 torture_comment(tctx, "inherited ACE not present!\n");
913 ret = false;
914 goto out;
915 }
916
917 out:
918 test_CloseKey(b, tctx, &new_handle);
919 test_Cleanup(b, tctx, handle, test_subkey_sd);
920 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
921
922 return ret;
923 }
924
test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)925 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
926 struct torture_context *tctx,
927 struct policy_handle *handle,
928 const char *key)
929 {
930 /* get sd
931 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
932 set sd
933 add subkey/subkey
934 get sd
935 check ace
936 get sd from subkey
937 check ace
938 del subkey/subkey
939 del subkey
940 reset sd
941 */
942
943 struct security_descriptor *sd = NULL;
944 struct security_descriptor *sd_orig = NULL;
945 struct security_ace *ace = NULL;
946 struct policy_handle new_handle;
947 struct dom_sid *sid = NULL;
948 bool ret = true;
949 uint8_t ace_flags = 0x0;
950 struct dcerpc_binding_handle *b = p->binding_handle;
951 const char *test_subkey_sd;
952 const char *test_subsubkey_sd;
953
954 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
955
956 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
957 return false;
958 }
959
960 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
961 return false;
962 }
963
964 sd_orig = security_descriptor_copy(tctx, sd);
965 if (sd_orig == NULL) {
966 return false;
967 }
968
969 ace = security_ace_create(tctx,
970 TEST_SID,
971 SEC_ACE_TYPE_ACCESS_ALLOWED,
972 SEC_STD_REQUIRED,
973 SEC_ACE_FLAG_CONTAINER_INHERIT |
974 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
975
976 torture_assert_ntstatus_ok(tctx,
977 security_descriptor_dacl_add(sd, ace),
978 "failed to add ace");
979
980 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
981 return false;
982 }
983
984 torture_assert(tctx,
985 test_dacl_ace_present(p, tctx, &new_handle, ace),
986 "new ACE not present!");
987
988 if (!test_CloseKey(b, tctx, &new_handle)) {
989 return false;
990 }
991
992 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
993 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
994
995 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
996 return false;
997 }
998
999 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
1000 ret = false;
1001 goto out;
1002 }
1003
1004 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1005 torture_comment(tctx, "inherited ACE present but should not!\n");
1006 ret = false;
1007 goto out;
1008 }
1009
1010 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1011 if (sid == NULL) {
1012 return false;
1013 }
1014
1015 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1016 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1017 ret = false;
1018 goto out;
1019 }
1020
1021 test_CloseKey(b, tctx, &new_handle);
1022
1023 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1024 ret = false;
1025 goto out;
1026 }
1027
1028 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1029 torture_comment(tctx, "inherited ACE present but should not!\n");
1030 ret = false;
1031 goto out;
1032 }
1033
1034 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1035 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1036 ace_flags);
1037 ret = false;
1038 goto out;
1039 }
1040
1041 out:
1042 test_CloseKey(b, tctx, &new_handle);
1043 test_Cleanup(b, tctx, handle, test_subkey_sd);
1044 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1045
1046 return ret;
1047 }
1048
test_SecurityDescriptorsMasks(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)1049 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1050 struct torture_context *tctx,
1051 struct policy_handle *handle,
1052 const char *key)
1053 {
1054 bool ret = true;
1055 int i;
1056
1057 struct winreg_mask_result_table {
1058 uint32_t access_mask;
1059 WERROR open_werr;
1060 WERROR get_werr;
1061 WERROR set_werr;
1062 } sd_mask_tests[] = {
1063 { 0,
1064 WERR_ACCESS_DENIED, WERR_FILE_NOT_FOUND, WERR_FOOBAR },
1065 { SEC_FLAG_MAXIMUM_ALLOWED,
1066 WERR_OK, WERR_OK, WERR_OK },
1067 { SEC_STD_WRITE_DAC,
1068 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1069 { SEC_FLAG_SYSTEM_SECURITY,
1070 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1071 };
1072
1073 /* FIXME: before this test can ever run successfully we need a way to
1074 * correctly read a NULL security_descritpor in ndr, get the required
1075 * length, requery, etc.
1076 */
1077
1078 return true;
1079
1080 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1081
1082 torture_comment(tctx,
1083 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1084 sd_mask_tests[i].access_mask);
1085 torture_comment(tctx,
1086 "expecting: open %s, get: %s, set: %s\n",
1087 win_errstr(sd_mask_tests[i].open_werr),
1088 win_errstr(sd_mask_tests[i].get_werr),
1089 win_errstr(sd_mask_tests[i].set_werr));
1090
1091 if (_test_SecurityDescriptor(p, tctx, handle,
1092 sd_mask_tests[i].access_mask, key,
1093 sd_mask_tests[i].open_werr,
1094 sd_mask_tests[i].get_werr,
1095 sd_mask_tests[i].set_werr)) {
1096 ret = false;
1097 }
1098 }
1099
1100 return ret;
1101 }
1102
1103 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1104 struct torture_context *,
1105 struct policy_handle *,
1106 const char *,
1107 const struct dom_sid *);
1108
test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key,const char * test,uint32_t access_mask,uint32_t sec_info,struct security_descriptor * sd,WERROR set_werr,bool expect_present,bool (* fn)(struct dcerpc_pipe *,struct torture_context *,struct policy_handle *,const char *,const struct dom_sid *),const struct dom_sid * sid)1109 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1110 struct torture_context *tctx,
1111 struct policy_handle *handle,
1112 const char *key,
1113 const char *test,
1114 uint32_t access_mask,
1115 uint32_t sec_info,
1116 struct security_descriptor *sd,
1117 WERROR set_werr,
1118 bool expect_present,
1119 bool (*fn) (struct dcerpc_pipe *,
1120 struct torture_context *,
1121 struct policy_handle *,
1122 const char *,
1123 const struct dom_sid *),
1124 const struct dom_sid *sid)
1125 {
1126 struct policy_handle new_handle;
1127 struct dcerpc_binding_handle *b = p->binding_handle;
1128
1129 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1130 "0x%08x, access_mask: 0x%08x\n",
1131 test, sec_info, access_mask);
1132
1133 torture_assert(tctx,
1134 test_OpenKey_opts(tctx, b, handle, key,
1135 REG_OPTION_NON_VOLATILE,
1136 access_mask,
1137 &new_handle,
1138 WERR_OK),
1139 "failed to open key");
1140
1141 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1142 sd,
1143 set_werr)) {
1144 torture_warning(tctx,
1145 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1146 sec_info);
1147 smb_panic("");
1148 test_CloseKey(b, tctx, &new_handle);
1149 return false;
1150 }
1151
1152 test_CloseKey(b, tctx, &new_handle);
1153
1154 if (W_ERROR_IS_OK(set_werr)) {
1155 bool present;
1156 present = fn(p, tctx, handle, key, sid);
1157 if ((expect_present) && (!present)) {
1158 torture_warning(tctx,
1159 "%s sid is not present!\n",
1160 test);
1161 return false;
1162 }
1163 if ((!expect_present) && (present)) {
1164 torture_warning(tctx,
1165 "%s sid is present but not expected!\n",
1166 test);
1167 return false;
1168 }
1169 }
1170
1171 return true;
1172 }
1173
test_SecurityDescriptorsSecInfo(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)1174 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1175 struct torture_context *tctx,
1176 struct policy_handle *handle,
1177 const char *key)
1178 {
1179 struct security_descriptor *sd_orig = NULL;
1180 struct dom_sid *sid = NULL;
1181 bool ret = true;
1182 int i, a;
1183
1184 struct security_descriptor *sd_owner =
1185 security_descriptor_dacl_create(tctx,
1186 0,
1187 TEST_SID, NULL, NULL);
1188
1189 struct security_descriptor *sd_group =
1190 security_descriptor_dacl_create(tctx,
1191 0,
1192 NULL, TEST_SID, NULL);
1193
1194 struct security_descriptor *sd_dacl =
1195 security_descriptor_dacl_create(tctx,
1196 0,
1197 NULL, NULL,
1198 TEST_SID,
1199 SEC_ACE_TYPE_ACCESS_ALLOWED,
1200 SEC_GENERIC_ALL,
1201 0,
1202 SID_NT_AUTHENTICATED_USERS,
1203 SEC_ACE_TYPE_ACCESS_ALLOWED,
1204 SEC_GENERIC_ALL,
1205 0,
1206 NULL);
1207
1208 struct security_descriptor *sd_sacl =
1209 security_descriptor_sacl_create(tctx,
1210 0,
1211 NULL, NULL,
1212 TEST_SID,
1213 SEC_ACE_TYPE_SYSTEM_AUDIT,
1214 SEC_GENERIC_ALL,
1215 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1216 NULL);
1217
1218 struct winreg_secinfo_table {
1219 struct security_descriptor *sd;
1220 uint32_t sec_info;
1221 WERROR set_werr;
1222 bool sid_present;
1223 secinfo_verify_fn fn;
1224 };
1225
1226 struct winreg_secinfo_table sec_info_owner_tests[] = {
1227 {
1228 .sd = sd_owner,
1229 .sec_info = 0,
1230 .set_werr = WERR_OK,
1231 .sid_present = false,
1232 .fn = (secinfo_verify_fn)_test_owner_present,
1233 },
1234 {
1235 .sd = sd_owner,
1236 .sec_info = SECINFO_OWNER,
1237 .set_werr = WERR_OK,
1238 .sid_present = true,
1239 .fn = (secinfo_verify_fn)_test_owner_present,
1240 },
1241 {
1242 .sd = sd_owner,
1243 .sec_info = SECINFO_GROUP,
1244 .set_werr = WERR_INVALID_PARAMETER,
1245 .sid_present = false,
1246 },
1247 {
1248 .sd = sd_owner,
1249 .sec_info = SECINFO_DACL,
1250 .set_werr = WERR_OK,
1251 .sid_present = true,
1252 .fn = (secinfo_verify_fn)_test_owner_present,
1253 },
1254 {
1255 .sd = sd_owner,
1256 .sec_info = SECINFO_SACL,
1257 .set_werr = WERR_ACCESS_DENIED,
1258 .sid_present = false,
1259 },
1260 };
1261
1262 uint32_t sd_owner_good_access_masks[] = {
1263 SEC_FLAG_MAXIMUM_ALLOWED,
1264 /* SEC_STD_WRITE_OWNER, */
1265 };
1266
1267 struct winreg_secinfo_table sec_info_group_tests[] = {
1268 {
1269 .sd = sd_group,
1270 .sec_info = 0,
1271 .set_werr = WERR_OK,
1272 .sid_present = false,
1273 .fn = (secinfo_verify_fn)_test_group_present,
1274 },
1275 {
1276 .sd = sd_group,
1277 .sec_info = SECINFO_OWNER,
1278 .set_werr = WERR_INVALID_PARAMETER,
1279 .sid_present = false,
1280 },
1281 {
1282 .sd = sd_group,
1283 .sec_info = SECINFO_GROUP,
1284 .set_werr = WERR_OK,
1285 .sid_present = true,
1286 .fn = (secinfo_verify_fn)_test_group_present,
1287 },
1288 {
1289 .sd = sd_group,
1290 .sec_info = SECINFO_DACL,
1291 .set_werr = WERR_OK,
1292 .sid_present = true,
1293 .fn = (secinfo_verify_fn)_test_group_present,
1294 },
1295 {
1296 .sd = sd_group,
1297 .sec_info = SECINFO_SACL,
1298 .set_werr = WERR_ACCESS_DENIED,
1299 .sid_present = false,
1300 },
1301 };
1302
1303 uint32_t sd_group_good_access_masks[] = {
1304 SEC_FLAG_MAXIMUM_ALLOWED,
1305 };
1306
1307 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1308 {
1309 .sd = sd_dacl,
1310 .sec_info = 0,
1311 .set_werr = WERR_OK,
1312 .sid_present = false,
1313 .fn = (secinfo_verify_fn)_test_dacl_trustee_present,
1314 },
1315 {
1316 .sd = sd_dacl,
1317 .sec_info = SECINFO_OWNER,
1318 .set_werr = WERR_INVALID_PARAMETER,
1319 .sid_present = false,
1320 },
1321 {
1322 .sd = sd_dacl,
1323 .sec_info = SECINFO_GROUP,
1324 .set_werr = WERR_INVALID_PARAMETER,
1325 .sid_present = false,
1326 },
1327 {
1328 .sd = sd_dacl,
1329 .sec_info = SECINFO_DACL,
1330 .set_werr = WERR_OK,
1331 .sid_present = true,
1332 .fn = (secinfo_verify_fn)_test_dacl_trustee_present
1333 },
1334 {
1335 .sd = sd_dacl,
1336 .sec_info = SECINFO_SACL,
1337 .set_werr = WERR_ACCESS_DENIED,
1338 .sid_present = false,
1339 },
1340 };
1341
1342 uint32_t sd_dacl_good_access_masks[] = {
1343 SEC_FLAG_MAXIMUM_ALLOWED,
1344 SEC_STD_WRITE_DAC,
1345 };
1346
1347 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1348 {
1349 .sd = sd_sacl,
1350 .sec_info = 0,
1351 .set_werr = WERR_OK,
1352 .sid_present = false,
1353 .fn = (secinfo_verify_fn)_test_sacl_trustee_present,
1354 },
1355 {
1356 .sd = sd_sacl,
1357 .sec_info = SECINFO_OWNER,
1358 .set_werr = WERR_INVALID_PARAMETER,
1359 .sid_present = false,
1360 },
1361 {
1362 .sd = sd_sacl,
1363 .sec_info = SECINFO_GROUP,
1364 .set_werr = WERR_INVALID_PARAMETER,
1365 .sid_present = false,
1366 },
1367 {
1368 .sd = sd_sacl,
1369 .sec_info = SECINFO_DACL,
1370 .set_werr = WERR_OK,
1371 .sid_present = false,
1372 .fn = (secinfo_verify_fn)_test_sacl_trustee_present,
1373 },
1374 {
1375 .sd = sd_sacl,
1376 .sec_info = SECINFO_SACL,
1377 .set_werr = WERR_OK,
1378 .sid_present = true,
1379 .fn = (secinfo_verify_fn)_test_sacl_trustee_present,
1380 },
1381 };
1382
1383 uint32_t sd_sacl_good_access_masks[] = {
1384 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1385 /* SEC_FLAG_SYSTEM_SECURITY, */
1386 };
1387
1388 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1389 if (sid == NULL) {
1390 return false;
1391 }
1392
1393 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1394 return false;
1395 }
1396
1397 /* OWNER */
1398
1399 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1400
1401 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1402
1403 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1404 key,
1405 "OWNER",
1406 sd_owner_good_access_masks[a],
1407 sec_info_owner_tests[i].sec_info,
1408 sec_info_owner_tests[i].sd,
1409 sec_info_owner_tests[i].set_werr,
1410 sec_info_owner_tests[i].sid_present,
1411 sec_info_owner_tests[i].fn,
1412 sid))
1413 {
1414 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1415 ret = false;
1416 goto out;
1417 }
1418 }
1419 }
1420
1421 /* GROUP */
1422
1423 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1424
1425 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1426
1427 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1428 key,
1429 "GROUP",
1430 sd_group_good_access_masks[a],
1431 sec_info_group_tests[i].sec_info,
1432 sec_info_group_tests[i].sd,
1433 sec_info_group_tests[i].set_werr,
1434 sec_info_group_tests[i].sid_present,
1435 sec_info_group_tests[i].fn,
1436 sid))
1437 {
1438 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1439 ret = false;
1440 goto out;
1441 }
1442 }
1443 }
1444
1445 /* DACL */
1446
1447 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1448
1449 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1450
1451 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1452 key,
1453 "DACL",
1454 sd_dacl_good_access_masks[a],
1455 sec_info_dacl_tests[i].sec_info,
1456 sec_info_dacl_tests[i].sd,
1457 sec_info_dacl_tests[i].set_werr,
1458 sec_info_dacl_tests[i].sid_present,
1459 sec_info_dacl_tests[i].fn,
1460 sid))
1461 {
1462 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1463 ret = false;
1464 goto out;
1465 }
1466 }
1467 }
1468
1469 /* SACL */
1470
1471 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1472
1473 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1474
1475 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1476 key,
1477 "SACL",
1478 sd_sacl_good_access_masks[a],
1479 sec_info_sacl_tests[i].sec_info,
1480 sec_info_sacl_tests[i].sd,
1481 sec_info_sacl_tests[i].set_werr,
1482 sec_info_sacl_tests[i].sid_present,
1483 sec_info_sacl_tests[i].fn,
1484 sid))
1485 {
1486 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1487 ret = false;
1488 goto out;
1489 }
1490 }
1491 }
1492
1493 out:
1494 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1495
1496 return ret;
1497 }
1498
test_SecurityDescriptors(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,const char * key)1499 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1500 struct torture_context *tctx,
1501 struct policy_handle *handle,
1502 const char *key)
1503 {
1504 bool ret = true;
1505
1506 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1507 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1508 ret = false;
1509 }
1510
1511 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1512 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1513 ret = false;
1514 }
1515
1516 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1517 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1518 ret = false;
1519 }
1520
1521 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1522 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1523 ret = false;
1524 }
1525
1526 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1527 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1528 ret = false;
1529 }
1530
1531 return ret;
1532 }
1533
test_DeleteKey_opts(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * key,WERROR expected_result)1534 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1535 struct torture_context *tctx,
1536 struct policy_handle *handle,
1537 const char *key,
1538 WERROR expected_result)
1539 {
1540 struct winreg_DeleteKey r;
1541
1542 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1543
1544 r.in.handle = handle;
1545 init_winreg_String(&r.in.key, key);
1546
1547 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1548 "Delete Key failed");
1549 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1550 "DeleteKey failed");
1551
1552 return true;
1553 }
1554
test_DeleteKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * key)1555 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1556 struct torture_context *tctx,
1557 struct policy_handle *handle, const char *key)
1558 {
1559 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1560 }
1561
test_QueryInfoKey(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,char * kclass,uint32_t * pmax_valnamelen,uint32_t * pmax_valbufsize)1562 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1563 struct torture_context *tctx,
1564 struct policy_handle *handle,
1565 char *kclass,
1566 uint32_t *pmax_valnamelen,
1567 uint32_t *pmax_valbufsize)
1568 {
1569 struct winreg_QueryInfoKey r;
1570 uint32_t num_subkeys, max_subkeylen, max_classlen,
1571 num_values, max_valnamelen, max_valbufsize,
1572 secdescsize;
1573 NTTIME last_changed_time;
1574
1575 ZERO_STRUCT(r);
1576 r.in.handle = handle;
1577 r.out.num_subkeys = &num_subkeys;
1578 r.out.max_subkeylen = &max_subkeylen;
1579 r.out.max_classlen = &max_classlen;
1580 r.out.num_values = &num_values;
1581 r.out.max_valnamelen = &max_valnamelen;
1582 r.out.max_valbufsize = &max_valbufsize;
1583 r.out.secdescsize = &secdescsize;
1584 r.out.last_changed_time = &last_changed_time;
1585
1586 r.out.classname = talloc(tctx, struct winreg_String);
1587
1588 r.in.classname = talloc(tctx, struct winreg_String);
1589 init_winreg_String(r.in.classname, kclass);
1590
1591 torture_assert_ntstatus_ok(tctx,
1592 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1593 "QueryInfoKey failed");
1594
1595 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1596
1597 if (pmax_valnamelen) {
1598 *pmax_valnamelen = max_valnamelen;
1599 }
1600
1601 if (pmax_valbufsize) {
1602 *pmax_valbufsize = max_valbufsize;
1603 }
1604
1605 return true;
1606 }
1607
test_SetValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * value_name,enum winreg_Type type,uint8_t * data,uint32_t size)1608 static bool test_SetValue(struct dcerpc_binding_handle *b,
1609 struct torture_context *tctx,
1610 struct policy_handle *handle,
1611 const char *value_name,
1612 enum winreg_Type type,
1613 uint8_t *data,
1614 uint32_t size)
1615 {
1616 struct winreg_SetValue r;
1617 struct winreg_String name;
1618
1619 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1620 value_name, str_regtype(type), size);
1621
1622 init_winreg_String(&name, value_name);
1623
1624 r.in.handle = handle;
1625 r.in.name = name;
1626 r.in.type = type;
1627 r.in.data = data;
1628 r.in.size = size;
1629
1630 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1631 "winreg_SetValue failed");
1632 torture_assert_werr_ok(tctx, r.out.result,
1633 "winreg_SetValue failed");
1634
1635 return true;
1636 }
1637
test_DeleteValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * value_name)1638 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1639 struct torture_context *tctx,
1640 struct policy_handle *handle,
1641 const char *value_name)
1642 {
1643 struct winreg_DeleteValue r;
1644 struct winreg_String value;
1645
1646 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1647
1648 init_winreg_String(&value, value_name);
1649
1650 r.in.handle = handle;
1651 r.in.value = value;
1652
1653 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1654 "winreg_DeleteValue failed");
1655 torture_assert_werr_ok(tctx, r.out.result,
1656 "winreg_DeleteValue failed");
1657
1658 return true;
1659 }
1660
1661 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1662 struct policy_handle *handle, int depth,
1663 bool test_security);
1664
test_EnumKey(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,int depth,bool test_security)1665 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1666 struct policy_handle *handle, int depth,
1667 bool test_security)
1668 {
1669 struct winreg_EnumKey r;
1670 struct winreg_StringBuf kclass, name;
1671 NTSTATUS status;
1672 NTTIME t = 0;
1673 struct dcerpc_binding_handle *b = p->binding_handle;
1674
1675 kclass.name = "";
1676 kclass.size = 1024;
1677
1678 ZERO_STRUCT(r);
1679 r.in.handle = handle;
1680 r.in.enum_index = 0;
1681 r.in.name = &name;
1682 r.in.keyclass = &kclass;
1683 r.out.name = &name;
1684 r.in.last_changed_time = &t;
1685
1686 do {
1687 name.name = NULL;
1688 name.size = 1024;
1689
1690 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1691
1692 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1693 struct policy_handle key_handle;
1694
1695 torture_comment(tctx, "EnumKey: %d: %s\n",
1696 r.in.enum_index,
1697 r.out.name->name);
1698
1699 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1700 &key_handle)) {
1701 } else {
1702 test_key(p, tctx, &key_handle,
1703 depth + 1, test_security);
1704 }
1705 }
1706
1707 r.in.enum_index++;
1708
1709 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1710
1711 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1712
1713 if (!W_ERROR_IS_OK(r.out.result) &&
1714 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1715 torture_fail(tctx, "EnumKey failed");
1716 }
1717
1718 return true;
1719 }
1720
test_QueryMultipleValues(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename)1721 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1722 struct torture_context *tctx,
1723 struct policy_handle *handle,
1724 const char *valuename)
1725 {
1726 struct winreg_QueryMultipleValues r;
1727 uint32_t bufsize=0;
1728
1729 ZERO_STRUCT(r);
1730
1731 r.in.key_handle = handle;
1732 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1733 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1734 r.in.values_in[0].ve_valuename->name = valuename;
1735 /* size needs to be set manually for winreg_ValNameBuf */
1736 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1737
1738 r.in.num_values = 1;
1739 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1740 *r.in.buffer_size = bufsize;
1741 do {
1742 *r.in.buffer_size = bufsize;
1743 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1744 *r.in.buffer_size);
1745
1746 torture_assert_ntstatus_ok(tctx,
1747 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1748 "QueryMultipleValues failed");
1749
1750 talloc_free(r.in.buffer);
1751 bufsize += 0x20;
1752 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1753
1754 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1755
1756 return true;
1757 }
1758
test_QueryMultipleValues_full(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,uint32_t num_values,const char * const * valuenames,bool existing_value)1759 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1760 struct torture_context *tctx,
1761 struct policy_handle *handle,
1762 uint32_t num_values,
1763 const char * const *valuenames,
1764 bool existing_value)
1765 {
1766 struct winreg_QueryMultipleValues r;
1767 uint32_t bufsize = 0;
1768 int i;
1769
1770 torture_comment(tctx, "Testing QueryMultipleValues\n");
1771
1772 ZERO_STRUCT(r);
1773
1774 r.in.key_handle = handle;
1775 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1776 r.in.buffer_size = r.out.buffer_size = &bufsize;
1777
1778 torture_assert_ntstatus_ok(tctx,
1779 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1780 "QueryMultipleValues failed");
1781 torture_assert_werr_ok(tctx, r.out.result,
1782 "QueryMultipleValues failed");
1783
1784 /* this test crashes w2k8 remote registry */
1785 #if 0
1786 r.in.num_values = num_values;
1787 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1788
1789 torture_assert_ntstatus_ok(tctx,
1790 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1791 "QueryMultipleValues failed");
1792 torture_assert_werr_ok(tctx, r.out.result,
1793 "QueryMultipleValues failed");
1794 #endif
1795 r.in.num_values = num_values;
1796 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1797 for (i=0; i < r.in.num_values; i++) {
1798 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1799 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1800 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1801 }
1802
1803 torture_assert_ntstatus_ok(tctx,
1804 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1805 "QueryMultipleValues failed");
1806 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1807 "QueryMultipleValues failed");
1808
1809 if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1810 return true;
1811 }
1812
1813 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1814 *r.in.buffer_size = 0xff;
1815 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1816
1817 torture_assert_ntstatus_ok(tctx,
1818 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1819 "QueryMultipleValues failed");
1820 }
1821
1822 torture_assert_werr_ok(tctx, r.out.result,
1823 "QueryMultipleValues failed");
1824
1825 return true;
1826 }
1827
1828
test_QueryMultipleValues2_full(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,uint32_t num_values,const char * const * valuenames,bool existing_value)1829 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1830 struct torture_context *tctx,
1831 struct policy_handle *handle,
1832 uint32_t num_values,
1833 const char * const *valuenames,
1834 bool existing_value)
1835 {
1836 struct winreg_QueryMultipleValues2 r;
1837 uint32_t offered = 0, needed;
1838 int i;
1839
1840 torture_comment(tctx, "Testing QueryMultipleValues2\n");
1841
1842 ZERO_STRUCT(r);
1843
1844 r.in.key_handle = handle;
1845 r.in.offered = &offered;
1846 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1847 r.out.needed = &needed;
1848
1849 torture_assert_ntstatus_ok(tctx,
1850 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1851 "QueryMultipleValues2 failed");
1852 torture_assert_werr_ok(tctx, r.out.result,
1853 "QueryMultipleValues2 failed");
1854
1855 /* this test crashes w2k8 remote registry */
1856 #if 0
1857 r.in.num_values = num_values;
1858 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1859
1860 torture_assert_ntstatus_ok(tctx,
1861 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1862 "QueryMultipleValues2 failed");
1863 torture_assert_werr_ok(tctx, r.out.result,
1864 "QueryMultipleValues2 failed");
1865 #endif
1866 r.in.num_values = num_values;
1867 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1868 for (i=0; i < r.in.num_values; i++) {
1869 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1870 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1871 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1872 }
1873
1874 torture_assert_ntstatus_ok(tctx,
1875 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1876 "QueryMultipleValues2 failed");
1877 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1878 "QueryMultipleValues2 failed");
1879
1880 if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1881 return true;
1882 }
1883
1884 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1885 *r.in.offered = *r.out.needed;
1886 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1887
1888 torture_assert_ntstatus_ok(tctx,
1889 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1890 "QueryMultipleValues2 failed");
1891 }
1892
1893 torture_assert_werr_ok(tctx, r.out.result,
1894 "QueryMultipleValues2 failed");
1895
1896 return true;
1897 }
1898
test_QueryMultipleValues2(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename)1899 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1900 struct torture_context *tctx,
1901 struct policy_handle *handle,
1902 const char *valuename)
1903 {
1904 struct winreg_QueryMultipleValues2 r;
1905 uint32_t offered = 0, needed;
1906
1907 ZERO_STRUCT(r);
1908
1909 r.in.key_handle = handle;
1910 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1911 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1912 r.in.values_in[0].ve_valuename->name = valuename;
1913 /* size needs to be set manually for winreg_ValNameBuf */
1914 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1915
1916 r.in.num_values = 1;
1917 r.in.offered = &offered;
1918 r.out.needed = &needed;
1919
1920 torture_assert_ntstatus_ok(tctx,
1921 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1922 "QueryMultipleValues2 failed");
1923 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1924 *r.in.offered = *r.out.needed;
1925 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1926
1927 torture_assert_ntstatus_ok(tctx,
1928 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1929 "QueryMultipleValues2 failed");
1930 }
1931
1932 torture_assert_werr_ok(tctx, r.out.result,
1933 "QueryMultipleValues2 failed");
1934
1935 return true;
1936 }
1937
test_QueryValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename)1938 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1939 struct torture_context *tctx,
1940 struct policy_handle *handle,
1941 const char *valuename)
1942 {
1943 struct winreg_QueryValue r;
1944 NTSTATUS status;
1945 enum winreg_Type zero_type = 0;
1946 uint32_t offered = 0xfff;
1947 uint32_t zero = 0;
1948
1949 ZERO_STRUCT(r);
1950 r.in.handle = handle;
1951 r.in.data = NULL;
1952 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1953 r.in.value_name->name = valuename;
1954 r.in.type = &zero_type;
1955 r.in.data_size = &offered;
1956 r.in.data_length = &zero;
1957
1958 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1959 if (NT_STATUS_IS_ERR(status)) {
1960 torture_fail(tctx, "QueryValue failed");
1961 }
1962
1963 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1964
1965 return true;
1966 }
1967
test_QueryValue_full(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,const char * valuename,bool existing_value)1968 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1969 struct torture_context *tctx,
1970 struct policy_handle *handle,
1971 const char *valuename,
1972 bool existing_value)
1973 {
1974 struct winreg_QueryValue r;
1975 struct winreg_String value_name;
1976 enum winreg_Type type = REG_NONE;
1977 uint32_t data_size = 0;
1978 uint32_t real_data_size = 0;
1979 uint32_t data_length = 0;
1980 uint8_t *data = NULL;
1981 WERROR expected_error = WERR_FILE_NOT_FOUND;
1982 const char *errmsg_nonexisting = "expected WERR_FILE_NOT_FOUND for nonexisting value";
1983
1984 if (valuename == NULL) {
1985 expected_error = WERR_INVALID_PARAMETER;
1986 errmsg_nonexisting = "expected WERR_INVALID_PARAMETER for NULL valuename";
1987 }
1988
1989 ZERO_STRUCT(r);
1990
1991 init_winreg_String(&value_name, NULL);
1992
1993 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1994
1995 r.in.handle = handle;
1996 r.in.value_name = &value_name;
1997
1998 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1999 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2000 "expected WERR_INVALID_PARAMETER for NULL winreg_String.name");
2001
2002 init_winreg_String(&value_name, valuename);
2003 r.in.value_name = &value_name;
2004
2005 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2006 "QueryValue failed");
2007 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2008 "expected WERR_INVALID_PARAMETER for missing type length and size");
2009
2010 r.in.type = &type;
2011 r.out.type = &type;
2012 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2013 "QueryValue failed");
2014 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2015 "expected WERR_INVALID_PARAMETER for missing length and size");
2016
2017 r.in.data_length = &data_length;
2018 r.out.data_length = &data_length;
2019 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2020 "QueryValue failed");
2021 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2022 "expected WERR_INVALID_PARAMETER for missing size");
2023
2024 r.in.data_size = &data_size;
2025 r.out.data_size = &data_size;
2026 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2027 "QueryValue failed");
2028 if (existing_value) {
2029 torture_assert_werr_ok(tctx, r.out.result,
2030 "QueryValue failed");
2031 } else {
2032 torture_assert_werr_equal(tctx, r.out.result, expected_error,
2033 errmsg_nonexisting);
2034 }
2035
2036 real_data_size = *r.out.data_size;
2037
2038 data = talloc_zero_array(tctx, uint8_t, 0);
2039 r.in.data = data;
2040 r.out.data = data;
2041 *r.in.data_size = 0;
2042 *r.out.data_size = 0;
2043 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2044 "QueryValue failed");
2045 if (existing_value) {
2046 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
2047 "expected WERR_MORE_DATA for query with too small buffer");
2048 } else {
2049 torture_assert_werr_equal(tctx, r.out.result, expected_error,
2050 errmsg_nonexisting);
2051 }
2052
2053 data = talloc_zero_array(tctx, uint8_t, real_data_size);
2054 r.in.data = data;
2055 r.out.data = data;
2056 r.in.data_size = &real_data_size;
2057 r.out.data_size = &real_data_size;
2058 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2059 "QueryValue failed");
2060 if (existing_value) {
2061 torture_assert_werr_ok(tctx, r.out.result,
2062 "QueryValue failed");
2063 } else {
2064 torture_assert_werr_equal(tctx, r.out.result, expected_error,
2065 errmsg_nonexisting);
2066 }
2067
2068 return true;
2069 }
2070
test_EnumValue(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle,int max_valnamelen,int max_valbufsize)2071 static bool test_EnumValue(struct dcerpc_binding_handle *b,
2072 struct torture_context *tctx,
2073 struct policy_handle *handle, int max_valnamelen,
2074 int max_valbufsize)
2075 {
2076 struct winreg_EnumValue r;
2077 enum winreg_Type type = 0;
2078 uint32_t size = max_valbufsize, zero = 0;
2079 bool ret = true;
2080 uint8_t *data = NULL;
2081 struct winreg_ValNameBuf name;
2082 char n = '\0';
2083
2084 ZERO_STRUCT(r);
2085 r.in.handle = handle;
2086 r.in.enum_index = 0;
2087 r.in.name = &name;
2088 r.out.name = &name;
2089 r.in.type = &type;
2090 r.in.length = &zero;
2091 r.in.size = &size;
2092
2093 do {
2094 name.name = &n;
2095 name.size = max_valnamelen + 2;
2096 name.length = 0;
2097
2098 data = NULL;
2099 if (size) {
2100 data = talloc_array(tctx, uint8_t, size);
2101 }
2102 r.in.value = data;
2103
2104 torture_assert_ntstatus_ok(tctx,
2105 dcerpc_winreg_EnumValue_r(b, tctx, &r),
2106 "EnumValue failed");
2107
2108 if (W_ERROR_IS_OK(r.out.result)) {
2109 ret &= test_QueryValue(b, tctx, handle,
2110 r.out.name->name);
2111 ret &= test_QueryMultipleValues(b, tctx, handle,
2112 r.out.name->name);
2113 ret &= test_QueryMultipleValues2(b, tctx, handle,
2114 r.out.name->name);
2115 }
2116
2117 talloc_free(data);
2118
2119 r.in.enum_index++;
2120 } while (W_ERROR_IS_OK(r.out.result));
2121
2122 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2123 "EnumValue failed");
2124
2125 return ret;
2126 }
2127
test_AbortSystemShutdown(struct dcerpc_binding_handle * b,struct torture_context * tctx)2128 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2129 struct torture_context *tctx)
2130 {
2131 struct winreg_AbortSystemShutdown r;
2132 uint16_t server = 0x0;
2133
2134 ZERO_STRUCT(r);
2135 r.in.server = &server;
2136
2137 torture_assert_ntstatus_ok(tctx,
2138 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2139 "AbortSystemShutdown failed");
2140
2141 torture_assert_werr_ok(tctx, r.out.result,
2142 "AbortSystemShutdown failed");
2143
2144 return true;
2145 }
2146
test_InitiateSystemShutdown(struct torture_context * tctx,struct dcerpc_pipe * p)2147 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2148 struct dcerpc_pipe *p)
2149 {
2150 struct winreg_InitiateSystemShutdown r;
2151 uint16_t hostname = 0x0;
2152 struct dcerpc_binding_handle *b = p->binding_handle;
2153
2154 ZERO_STRUCT(r);
2155 r.in.hostname = &hostname;
2156 r.in.message = talloc(tctx, struct lsa_StringLarge);
2157 init_lsa_StringLarge(r.in.message, "spottyfood");
2158 r.in.force_apps = 1;
2159 r.in.timeout = 30;
2160 r.in.do_reboot = 1;
2161
2162 torture_assert_ntstatus_ok(tctx,
2163 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2164 "InitiateSystemShutdown failed");
2165
2166 torture_assert_werr_ok(tctx, r.out.result,
2167 "InitiateSystemShutdown failed");
2168
2169 return test_AbortSystemShutdown(b, tctx);
2170 }
2171
2172
test_InitiateSystemShutdownEx(struct torture_context * tctx,struct dcerpc_pipe * p)2173 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2174 struct dcerpc_pipe *p)
2175 {
2176 struct winreg_InitiateSystemShutdownEx r;
2177 uint16_t hostname = 0x0;
2178 struct dcerpc_binding_handle *b = p->binding_handle;
2179
2180 ZERO_STRUCT(r);
2181 r.in.hostname = &hostname;
2182 r.in.message = talloc(tctx, struct lsa_StringLarge);
2183 init_lsa_StringLarge(r.in.message, "spottyfood");
2184 r.in.force_apps = 1;
2185 r.in.timeout = 30;
2186 r.in.do_reboot = 1;
2187 r.in.reason = 0;
2188
2189 torture_assert_ntstatus_ok(tctx,
2190 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2191 "InitiateSystemShutdownEx failed");
2192
2193 torture_assert_werr_ok(tctx, r.out.result,
2194 "InitiateSystemShutdownEx failed");
2195
2196 return test_AbortSystemShutdown(b, tctx);
2197 }
2198 #define MAX_DEPTH 2 /* Only go this far down the tree */
2199
test_key(struct dcerpc_pipe * p,struct torture_context * tctx,struct policy_handle * handle,int depth,bool test_security)2200 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2201 struct policy_handle *handle, int depth,
2202 bool test_security)
2203 {
2204 struct dcerpc_binding_handle *b = p->binding_handle;
2205 uint32_t max_valnamelen = 0;
2206 uint32_t max_valbufsize = 0;
2207
2208 if (depth == MAX_DEPTH)
2209 return true;
2210
2211 if (!test_QueryInfoKey(b, tctx, handle, NULL,
2212 &max_valnamelen, &max_valbufsize)) {
2213 }
2214
2215 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2216 }
2217
2218 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2219 }
2220
2221 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2222 }
2223
2224 if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2225 }
2226
2227 if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2228 }
2229
2230 test_CloseKey(b, tctx, handle);
2231
2232 return true;
2233 }
2234
test_SetValue_simple(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2235 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2236 struct torture_context *tctx,
2237 struct policy_handle *handle)
2238 {
2239 const char *value_name = TEST_VALUE;
2240 uint32_t value = 0x12345678;
2241 uint64_t value2 = 0x12345678;
2242 const char *string = "torture";
2243 const char *array[2];
2244 DATA_BLOB blob;
2245 enum winreg_Type types[] = {
2246 REG_DWORD,
2247 REG_DWORD_BIG_ENDIAN,
2248 REG_QWORD,
2249 REG_BINARY,
2250 REG_SZ,
2251 REG_MULTI_SZ
2252 };
2253 int t;
2254
2255 array[0] = "array0";
2256 array[1] = NULL;
2257
2258 torture_comment(tctx, "Testing SetValue (standard formats)\n");
2259
2260 for (t=0; t < ARRAY_SIZE(types); t++) {
2261
2262 enum winreg_Type w_type;
2263 uint32_t w_size, w_length;
2264 uint8_t *w_data;
2265
2266 switch (types[t]) {
2267 case REG_DWORD:
2268 case REG_DWORD_BIG_ENDIAN:
2269 blob = data_blob_talloc_zero(tctx, 4);
2270 SIVAL(blob.data, 0, value);
2271 break;
2272 case REG_QWORD:
2273 blob = data_blob_talloc_zero(tctx, 8);
2274 SBVAL(blob.data, 0, value2);
2275 break;
2276 case REG_BINARY:
2277 blob = data_blob_string_const("binary_blob");
2278 break;
2279 case REG_SZ:
2280 torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2281 break;
2282 case REG_MULTI_SZ:
2283 torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2284 break;
2285 default:
2286 break;
2287 }
2288
2289 torture_assert(tctx,
2290 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2291 "test_SetValue failed");
2292 torture_assert(tctx,
2293 test_QueryValue_full(b, tctx, handle, value_name, true),
2294 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2295 torture_assert(tctx,
2296 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2297 "test_winreg_QueryValue failed");
2298 torture_assert(tctx,
2299 test_DeleteValue(b, tctx, handle, value_name),
2300 "test_DeleteValue failed");
2301
2302 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2303 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2304 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2305 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2306 }
2307
2308 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2309
2310 return true;
2311 }
2312
test_SetValue_values(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2313 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2314 struct torture_context *tctx,
2315 struct policy_handle *handle)
2316 {
2317 DATA_BLOB blob;
2318 const char *values[] = {
2319 "torture_value",
2320 "torture value",
2321 "torture,value",
2322 "torture;value",
2323 "torture/value",
2324 "torture\\value",
2325 "torture_value_name",
2326 "torture value name",
2327 "torture,value,name",
2328 "torture;value;name",
2329 "torture/value/name",
2330 "torture\\value\\name",
2331 };
2332 int i;
2333
2334 torture_comment(tctx, "Testing SetValue (values)\n");
2335
2336 for (i=0; i < ARRAY_SIZE(values); i++) {
2337
2338 enum winreg_Type w_type;
2339 uint32_t w_size, w_length;
2340 uint8_t *w_data;
2341
2342 blob = data_blob_talloc(tctx, NULL, 32);
2343
2344 generate_random_buffer(blob.data, 32);
2345
2346 torture_assert(tctx,
2347 test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2348 "test_SetValue failed");
2349 torture_assert(tctx,
2350 test_QueryValue_full(b, tctx, handle, values[i], true),
2351 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2352 torture_assert(tctx,
2353 test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2354 "test_winreg_QueryValue failed");
2355 torture_assert(tctx,
2356 test_DeleteValue(b, tctx, handle, values[i]),
2357 "test_DeleteValue failed");
2358
2359 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2360 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2361 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2362 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2363 }
2364
2365 torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2366
2367 return true;
2368 }
2369
2370 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2371
test_SetValue_extended(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2372 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2373 struct torture_context *tctx,
2374 struct policy_handle *handle)
2375 {
2376 const char *value_name = TEST_VALUE;
2377 enum winreg_Type types[] = {
2378 REG_NONE,
2379 REG_SZ,
2380 REG_EXPAND_SZ,
2381 REG_BINARY,
2382 REG_DWORD,
2383 REG_DWORD_BIG_ENDIAN,
2384 REG_LINK,
2385 REG_MULTI_SZ,
2386 REG_RESOURCE_LIST,
2387 REG_FULL_RESOURCE_DESCRIPTOR,
2388 REG_RESOURCE_REQUIREMENTS_LIST,
2389 REG_QWORD,
2390 12,
2391 13,
2392 14,
2393 55,
2394 123456,
2395 653210,
2396 __LINE__
2397 };
2398 int t, l;
2399
2400 if (torture_setting_bool(tctx, "samba4", false)) {
2401 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2402 }
2403
2404 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2405
2406 for (t=0; t < ARRAY_SIZE(types); t++) {
2407 for (l=0; l < 16; l++) {
2408
2409 enum winreg_Type w_type;
2410 uint32_t w_size, w_length;
2411 uint8_t *w_data;
2412
2413 uint32_t size;
2414 uint8_t *data;
2415
2416 size = l;
2417 data = talloc_array(tctx, uint8_t, size);
2418
2419 generate_random_buffer(data, size);
2420
2421 torture_assert(tctx,
2422 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2423 "test_SetValue failed");
2424
2425 torture_assert(tctx,
2426 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2427 "test_winreg_QueryValue failed");
2428
2429 torture_assert(tctx,
2430 test_DeleteValue(b, tctx, handle, value_name),
2431 "test_DeleteValue failed");
2432
2433 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2434 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2435 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2436 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2437 }
2438 }
2439
2440 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2441
2442 return true;
2443 }
2444
test_create_keynames(struct dcerpc_binding_handle * b,struct torture_context * tctx,struct policy_handle * handle)2445 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2446 struct torture_context *tctx,
2447 struct policy_handle *handle)
2448 {
2449 const char *keys[] = {
2450 "torture_key",
2451 "torture key",
2452 "torture,key",
2453 "torture/key",
2454 "torture\\key",
2455 };
2456 int i;
2457
2458 for (i=0; i < ARRAY_SIZE(keys); i++) {
2459
2460 enum winreg_CreateAction action_taken;
2461 struct policy_handle new_handle;
2462 char *q, *tmp;
2463
2464 torture_assert(tctx,
2465 test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2466 REG_OPTION_NON_VOLATILE,
2467 SEC_FLAG_MAXIMUM_ALLOWED,
2468 NULL,
2469 WERR_OK,
2470 &action_taken,
2471 &new_handle),
2472 talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2473
2474 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2475
2476 torture_assert(tctx,
2477 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2478 "failed to delete key");
2479
2480 torture_assert(tctx,
2481 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_FILE_NOT_FOUND),
2482 "failed 2nd delete key");
2483
2484 tmp = talloc_strdup(tctx, keys[i]);
2485
2486 q = strchr(tmp, '\\');
2487 if (q != NULL) {
2488 *q = '\0';
2489 q++;
2490
2491 torture_assert(tctx,
2492 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2493 "failed to delete key");
2494
2495 torture_assert(tctx,
2496 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_FILE_NOT_FOUND),
2497 "failed 2nd delete key");
2498 }
2499 }
2500
2501 return true;
2502 }
2503
2504 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2505 #define VALUE_CURRENT_VERSION "CurrentVersion"
2506 #define VALUE_SYSTEM_ROOT "SystemRoot"
2507
2508 static const struct {
2509 const char *values[3];
2510 uint32_t num_values;
2511 bool existing_value;
2512 const char *error_message;
2513 } multiple_values_tests[] = {
2514 {
2515 .values = { VALUE_CURRENT_VERSION, NULL, NULL },
2516 .num_values = 1,
2517 .existing_value = true,
2518 .error_message = NULL
2519 },{
2520 .values = { VALUE_SYSTEM_ROOT, NULL, NULL },
2521 .num_values = 1,
2522 .existing_value = true,
2523 .error_message = NULL
2524 },{
2525 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT, NULL },
2526 .num_values = 2,
2527 .existing_value = true,
2528 .error_message = NULL
2529 },{
2530 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT,
2531 VALUE_CURRENT_VERSION },
2532 .num_values = 3,
2533 .existing_value = true,
2534 .error_message = NULL
2535 },{
2536 .values = { VALUE_CURRENT_VERSION, NULL, VALUE_SYSTEM_ROOT },
2537 .num_values = 3,
2538 .existing_value = false,
2539 .error_message = NULL
2540 },{
2541 .values = { VALUE_CURRENT_VERSION, "", VALUE_SYSTEM_ROOT },
2542 .num_values = 3,
2543 .existing_value = false,
2544 .error_message = NULL
2545 },{
2546 .values = { "IDoNotExist", NULL, NULL },
2547 .num_values = 1,
2548 .existing_value = false,
2549 .error_message = NULL
2550 },{
2551 .values = { "IDoNotExist", VALUE_CURRENT_VERSION, NULL },
2552 .num_values = 2,
2553 .existing_value = false,
2554 .error_message = NULL
2555 },{
2556 .values = { VALUE_CURRENT_VERSION, "IDoNotExist", NULL },
2557 .num_values = 2,
2558 .existing_value = false,
2559 .error_message = NULL
2560 }
2561 };
2562
test_HKLM_wellknown(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle)2563 static bool test_HKLM_wellknown(struct torture_context *tctx,
2564 struct dcerpc_binding_handle *b,
2565 struct policy_handle *handle)
2566 {
2567 struct policy_handle newhandle;
2568 int i;
2569
2570 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2571 if (torture_setting_bool(tctx, "samba3", false)) {
2572 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2573 KEY_CURRENT_VERSION,
2574 REG_OPTION_NON_VOLATILE,
2575 KEY_QUERY_VALUE,
2576 &newhandle,
2577 WERR_OK),
2578 "failed to open current version key");
2579 } else {
2580 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2581 "failed to open current version key");
2582 }
2583
2584 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2585 "failed to query current version");
2586 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2587 "succeeded to query nonexistent value");
2588 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2589 "succeeded to query value with NULL name");
2590 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2591 "succeeded to query nonexistent default value (\"\")");
2592
2593 if (torture_setting_bool(tctx, "samba4", false)) {
2594 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2595 goto close_key;
2596 }
2597
2598 for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2599 const char *msg;
2600 msg = talloc_asprintf(tctx,
2601 "failed to query %d %sexisting values\n",
2602 multiple_values_tests[i].num_values,
2603 multiple_values_tests[i].existing_value ? "":"non");
2604
2605 torture_assert(tctx,
2606 test_QueryMultipleValues_full(b, tctx, &newhandle,
2607 multiple_values_tests[i].num_values,
2608 multiple_values_tests[i].values,
2609 multiple_values_tests[i].existing_value),
2610 msg);
2611 torture_assert(tctx,
2612 test_QueryMultipleValues2_full(b, tctx, &newhandle,
2613 multiple_values_tests[i].num_values,
2614 multiple_values_tests[i].values,
2615 multiple_values_tests[i].existing_value),
2616 msg);
2617 }
2618
2619 close_key:
2620 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2621 "failed to close current version key");
2622
2623 return true;
2624 }
2625
test_OpenHive(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,int hkey)2626 static bool test_OpenHive(struct torture_context *tctx,
2627 struct dcerpc_binding_handle *b,
2628 struct policy_handle *handle,
2629 int hkey)
2630 {
2631 struct winreg_OpenHKLM r;
2632
2633 r.in.system_name = 0;
2634 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2635 r.out.handle = handle;
2636
2637 switch (hkey) {
2638 case HKEY_LOCAL_MACHINE:
2639 torture_assert_ntstatus_ok(tctx,
2640 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2641 "failed to open HKLM");
2642 torture_assert_werr_ok(tctx, r.out.result,
2643 "failed to open HKLM");
2644 break;
2645 case HKEY_CURRENT_USER:
2646 torture_assert_ntstatus_ok(tctx,
2647 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2648 "failed to open HKCU");
2649 torture_assert_werr_ok(tctx, r.out.result,
2650 "failed to open HKCU");
2651 break;
2652 case HKEY_USERS:
2653 torture_assert_ntstatus_ok(tctx,
2654 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2655 "failed to open HKU");
2656 torture_assert_werr_ok(tctx, r.out.result,
2657 "failed to open HKU");
2658 break;
2659 case HKEY_CLASSES_ROOT:
2660 torture_assert_ntstatus_ok(tctx,
2661 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2662 "failed to open HKCR");
2663 torture_assert_werr_ok(tctx, r.out.result,
2664 "failed to open HKCR");
2665 break;
2666 default:
2667 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2668 return false;
2669 }
2670
2671 return true;
2672 }
2673
test_volatile_keys(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,int hkey)2674 static bool test_volatile_keys(struct torture_context *tctx,
2675 struct dcerpc_binding_handle *b,
2676 struct policy_handle *handle,
2677 int hkey)
2678 {
2679 struct policy_handle new_handle, hive_handle;
2680 enum winreg_CreateAction action_taken = REG_ACTION_NONE;
2681
2682 ZERO_STRUCT(new_handle);
2683 ZERO_STRUCT(hive_handle);
2684
2685 torture_comment(tctx, "Testing VOLATILE key\n");
2686
2687 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2688
2689 torture_assert(tctx,
2690 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2691 REG_OPTION_VOLATILE,
2692 SEC_FLAG_MAXIMUM_ALLOWED,
2693 NULL,
2694 WERR_OK,
2695 &action_taken,
2696 &new_handle),
2697 "failed to create REG_OPTION_VOLATILE type key");
2698
2699 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2700
2701 torture_assert(tctx,
2702 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2703 REG_OPTION_NON_VOLATILE,
2704 SEC_FLAG_MAXIMUM_ALLOWED,
2705 NULL,
2706 WERR_CHILD_MUST_BE_VOLATILE,
2707 NULL,
2708 NULL),
2709 "failed to fail create REG_OPTION_VOLATILE type key");
2710
2711 torture_assert(tctx,
2712 test_CloseKey(b, tctx, &new_handle),
2713 "failed to close");
2714
2715 torture_assert(tctx,
2716 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2717 REG_OPTION_NON_VOLATILE,
2718 SEC_FLAG_MAXIMUM_ALLOWED,
2719 &new_handle,
2720 WERR_OK),
2721 "failed to open volatile key");
2722
2723 torture_assert(tctx,
2724 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2725 "failed to delete key");
2726
2727 torture_assert(tctx,
2728 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2729 REG_OPTION_VOLATILE,
2730 SEC_FLAG_MAXIMUM_ALLOWED,
2731 NULL,
2732 WERR_OK,
2733 &action_taken,
2734 &new_handle),
2735 "failed to create REG_OPTION_VOLATILE type key");
2736
2737 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2738
2739 torture_assert(tctx,
2740 test_CloseKey(b, tctx, &new_handle),
2741 "failed to close");
2742
2743 torture_assert(tctx,
2744 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2745 REG_OPTION_VOLATILE,
2746 SEC_FLAG_MAXIMUM_ALLOWED,
2747 &new_handle,
2748 WERR_OK),
2749 "failed to open volatile key");
2750
2751 torture_assert(tctx,
2752 test_CloseKey(b, tctx, &new_handle),
2753 "failed to close");
2754
2755 torture_assert(tctx,
2756 test_OpenHive(tctx, b, &hive_handle, hkey),
2757 "failed top open hive");
2758
2759 torture_assert(tctx,
2760 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2761 REG_OPTION_VOLATILE,
2762 SEC_FLAG_MAXIMUM_ALLOWED,
2763 &new_handle,
2764 WERR_FILE_NOT_FOUND),
2765 "failed to open volatile key");
2766
2767 torture_assert(tctx,
2768 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2769 REG_OPTION_NON_VOLATILE,
2770 SEC_FLAG_MAXIMUM_ALLOWED,
2771 &new_handle,
2772 WERR_FILE_NOT_FOUND),
2773 "failed to open volatile key");
2774
2775 torture_assert(tctx,
2776 test_CloseKey(b, tctx, &hive_handle),
2777 "failed to close");
2778
2779 torture_assert(tctx,
2780 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2781 "failed to delete key");
2782
2783
2784 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2785
2786 return true;
2787 }
2788
kernel_mode_registry_path(struct torture_context * tctx,int hkey,const char * sid_string,const char * path)2789 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2790 int hkey,
2791 const char *sid_string,
2792 const char *path)
2793 {
2794 switch (hkey) {
2795 case HKEY_LOCAL_MACHINE:
2796 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2797 case HKEY_CURRENT_USER:
2798 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2799 case HKEY_USERS:
2800 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2801 case HKEY_CLASSES_ROOT:
2802 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2803 default:
2804 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2805 return NULL;
2806 }
2807 }
2808
test_symlink_keys(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * key,int hkey)2809 static bool test_symlink_keys(struct torture_context *tctx,
2810 struct dcerpc_binding_handle *b,
2811 struct policy_handle *handle,
2812 const char *key,
2813 int hkey)
2814 {
2815 struct policy_handle new_handle;
2816 enum winreg_CreateAction action_taken;
2817 DATA_BLOB blob;
2818 uint32_t value = 42;
2819 const char *test_key_symlink_dest;
2820 const char *test_key_symlink;
2821 const char *kernel_mode_path;
2822
2823 /* disable until we know how to delete a symbolic link */
2824 torture_skip(tctx, "symlink test disabled");
2825
2826 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2827
2828 /* create destination key with testvalue */
2829 test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2830 key, TEST_KEY_SYMLINK);
2831 test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2832 key, TEST_KEY_SYMLINK_DEST);
2833
2834 test_DeleteKey(b, tctx, handle, test_key_symlink);
2835
2836 torture_assert(tctx,
2837 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2838 0,
2839 SEC_FLAG_MAXIMUM_ALLOWED,
2840 NULL,
2841 WERR_OK,
2842 &action_taken,
2843 &new_handle),
2844 "failed to create symlink destination");
2845
2846 blob = data_blob_talloc_zero(tctx, 4);
2847 SIVAL(blob.data, 0, value);
2848
2849 torture_assert(tctx,
2850 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2851 "failed to create TestValue");
2852
2853 torture_assert(tctx,
2854 test_CloseKey(b, tctx, &new_handle),
2855 "failed to close");
2856
2857 /* create symlink */
2858
2859 torture_assert(tctx,
2860 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2861 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2862 SEC_FLAG_MAXIMUM_ALLOWED,
2863 NULL,
2864 WERR_OK,
2865 &action_taken,
2866 &new_handle),
2867 "failed to create REG_OPTION_CREATE_LINK type key");
2868
2869 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2870
2871 kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2872
2873 torture_assert(tctx,
2874 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2875 kernel_mode_path,
2876 strlen(kernel_mode_path), /* not NULL terminated */
2877 &blob.data, &blob.length),
2878 "failed to convert");
2879
2880 torture_assert(tctx,
2881 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2882 "failed to create SymbolicLinkValue value");
2883
2884 torture_assert(tctx,
2885 test_CloseKey(b, tctx, &new_handle),
2886 "failed to close");
2887
2888 /* test follow symlink */
2889
2890 torture_assert(tctx,
2891 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2892 0,
2893 SEC_FLAG_MAXIMUM_ALLOWED,
2894 &new_handle,
2895 WERR_OK),
2896 "failed to follow symlink key");
2897
2898 torture_assert(tctx,
2899 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2900 "failed to query value");
2901
2902 torture_assert(tctx,
2903 test_CloseKey(b, tctx, &new_handle),
2904 "failed to close");
2905
2906 /* delete link */
2907
2908 torture_assert(tctx,
2909 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2910 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2911 SEC_FLAG_MAXIMUM_ALLOWED,
2912 &new_handle,
2913 WERR_OK),
2914 "failed to open symlink key");
2915
2916 torture_assert(tctx,
2917 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2918 "failed to delete value SymbolicLinkValue");
2919
2920 torture_assert(tctx,
2921 test_CloseKey(b, tctx, &new_handle),
2922 "failed to close");
2923
2924 torture_assert(tctx,
2925 test_DeleteKey(b, tctx, handle, test_key_symlink),
2926 "failed to delete key");
2927
2928 /* delete destination */
2929
2930 torture_assert(tctx,
2931 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2932 "failed to delete key");
2933
2934 return true;
2935 }
2936
test_CreateKey_keytypes(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * key,int hkey)2937 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2938 struct dcerpc_binding_handle *b,
2939 struct policy_handle *handle,
2940 const char *key,
2941 int hkey)
2942 {
2943
2944 if (torture_setting_bool(tctx, "samba3", false) ||
2945 torture_setting_bool(tctx, "samba4", false)) {
2946 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2947 }
2948
2949 torture_assert(tctx,
2950 test_volatile_keys(tctx, b, handle, hkey),
2951 "failed to test volatile keys");
2952
2953 torture_assert(tctx,
2954 test_symlink_keys(tctx, b, handle, key, hkey),
2955 "failed to test symlink keys");
2956
2957 return true;
2958 }
2959
test_key_base(struct torture_context * tctx,struct dcerpc_binding_handle * b,struct policy_handle * handle,const char * base_key,int hkey)2960 static bool test_key_base(struct torture_context *tctx,
2961 struct dcerpc_binding_handle *b,
2962 struct policy_handle *handle,
2963 const char *base_key,
2964 int hkey)
2965 {
2966 struct policy_handle newhandle;
2967 bool ret = true, created = false, deleted = false;
2968 bool created3 = false;
2969 const char *test_key1;
2970 const char *test_key3;
2971 const char *test_subkey;
2972
2973 test_Cleanup(b, tctx, handle, base_key);
2974
2975 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2976 torture_comment(tctx,
2977 "CreateKey(%s) failed\n", base_key);
2978 }
2979
2980 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2981
2982 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2983 torture_comment(tctx,
2984 "CreateKey failed - not considering a failure\n");
2985 } else {
2986 created = true;
2987 }
2988
2989 if (created) {
2990 if (!test_FlushKey(b, tctx, handle)) {
2991 torture_comment(tctx, "FlushKey failed\n");
2992 ret = false;
2993 }
2994
2995 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2996 torture_fail(tctx,
2997 "CreateKey failed (OpenKey after Create didn't work)\n");
2998 }
2999
3000 if (hkey == HKEY_CURRENT_USER) {
3001 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
3002 "simple SetValue test failed");
3003 torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
3004 "values SetValue test failed");
3005 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
3006 "extended SetValue test failed");
3007 torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
3008 "keyname CreateKey test failed");
3009 } else {
3010 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
3011 "keytype test failed");
3012 }
3013
3014 if (!test_CloseKey(b, tctx, &newhandle)) {
3015 torture_fail(tctx,
3016 "CreateKey failed (CloseKey after Open didn't work)\n");
3017 }
3018
3019 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
3020 torture_comment(tctx, "DeleteKey(%s) failed\n",
3021 test_key1);
3022 ret = false;
3023 } else {
3024 deleted = true;
3025 }
3026
3027 if (!test_FlushKey(b, tctx, handle)) {
3028 torture_comment(tctx, "FlushKey failed\n");
3029 ret = false;
3030 }
3031
3032 if (deleted) {
3033 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
3034 REG_OPTION_NON_VOLATILE,
3035 SEC_FLAG_MAXIMUM_ALLOWED,
3036 &newhandle,
3037 WERR_FILE_NOT_FOUND)) {
3038 torture_comment(tctx,
3039 "DeleteKey failed (OpenKey after Delete "
3040 "did not return WERR_FILE_NOT_FOUND)\n");
3041 ret = false;
3042 }
3043 }
3044
3045 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
3046
3047 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
3048 created3 = true;
3049 }
3050
3051 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
3052
3053 if (created3) {
3054 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
3055 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
3056 torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
3057 ret = false;
3058 }
3059 }
3060
3061 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
3062 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
3063 ret = false;
3064 }
3065 }
3066 }
3067
3068 test_Cleanup(b, tctx, handle, base_key);
3069
3070 return ret;
3071 }
3072
test_key_base_sd(struct torture_context * tctx,struct dcerpc_pipe * p,struct policy_handle * handle,const char * base_key)3073 static bool test_key_base_sd(struct torture_context *tctx,
3074 struct dcerpc_pipe *p,
3075 struct policy_handle *handle,
3076 const char *base_key)
3077 {
3078 struct policy_handle newhandle;
3079 bool ret = true, created2 = false, created4 = false;
3080 struct dcerpc_binding_handle *b = p->binding_handle;
3081 const char *test_key2;
3082 const char *test_key4;
3083
3084 torture_skip(tctx, "security descriptor test disabled\n");
3085
3086 if (torture_setting_bool(tctx, "samba3", false) ||
3087 torture_setting_bool(tctx, "samba4", false)) {
3088 torture_skip(tctx, "skipping security descriptor tests against Samba");
3089 }
3090
3091 test_Cleanup(b, tctx, handle, base_key);
3092
3093 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
3094 torture_comment(tctx,
3095 "CreateKey(%s) failed\n", base_key);
3096 }
3097
3098 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
3099
3100 if (test_CreateKey_sd(b, tctx, handle, test_key2,
3101 NULL, &newhandle)) {
3102 created2 = true;
3103 }
3104
3105 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3106 torture_comment(tctx, "CloseKey failed\n");
3107 ret = false;
3108 }
3109
3110 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3111
3112 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3113 created4 = true;
3114 }
3115
3116 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3117 torture_comment(tctx, "CloseKey failed\n");
3118 ret = false;
3119 }
3120
3121 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3122 ret = false;
3123 }
3124
3125 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3126 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3127 ret = false;
3128 }
3129
3130 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3131 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3132 ret = false;
3133 }
3134
3135 test_Cleanup(b, tctx, handle, base_key);
3136
3137 return ret;
3138 }
3139
test_Open(struct torture_context * tctx,struct dcerpc_pipe * p,void * userdata)3140 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3141 void *userdata)
3142 {
3143 struct policy_handle handle;
3144 bool ret = true;
3145 struct winreg_OpenHKLM r;
3146 struct dcerpc_binding_handle *b = p->binding_handle;
3147 const char *torture_base_key;
3148 int hkey = 0;
3149
3150 winreg_open_fn open_fn = (winreg_open_fn)userdata;
3151
3152 r.in.system_name = 0;
3153 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3154 r.out.handle = &handle;
3155
3156 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3157 "open");
3158
3159 if (!test_GetVersion(b, tctx, &handle)) {
3160 torture_comment(tctx, "GetVersion failed\n");
3161 ret = false;
3162 }
3163
3164 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3165 hkey = HKEY_LOCAL_MACHINE;
3166 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3167 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3168 hkey = HKEY_USERS;
3169 torture_base_key = TEST_KEY_BASE;
3170 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3171 hkey = HKEY_CLASSES_ROOT;
3172 torture_base_key = TEST_KEY_BASE;
3173 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3174 hkey = HKEY_CURRENT_USER;
3175 torture_base_key = TEST_KEY_BASE;
3176 } else {
3177 torture_fail(tctx, "unsupported hkey");
3178 }
3179
3180 if (hkey == HKEY_LOCAL_MACHINE) {
3181 torture_assert(tctx,
3182 test_HKLM_wellknown(tctx, b, &handle),
3183 "failed to test HKLM wellknown keys");
3184 }
3185
3186 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3187 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3188 torture_base_key);
3189 ret = false;
3190 }
3191
3192 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3193 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3194 torture_base_key);
3195 ret = false;
3196 }
3197
3198 /* The HKCR hive has a very large fanout */
3199 if (hkey == HKEY_CLASSES_ROOT) {
3200 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3201 ret = false;
3202 }
3203 } else if (hkey == HKEY_LOCAL_MACHINE) {
3204 /* FIXME we are not allowed to enum values in the HKLM root */
3205 } else {
3206 if (!test_key(p, tctx, &handle, 0, false)) {
3207 ret = false;
3208 }
3209 }
3210
3211 return ret;
3212 }
3213
torture_rpc_winreg(TALLOC_CTX * mem_ctx)3214 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3215 {
3216 struct torture_rpc_tcase *tcase;
3217 struct torture_suite *suite = torture_suite_create(mem_ctx, "winreg");
3218 struct torture_test *test;
3219
3220 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3221 &ndr_table_winreg);
3222
3223 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3224 test_InitiateSystemShutdown);
3225 test->dangerous = true;
3226
3227 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3228 test_InitiateSystemShutdownEx);
3229 test->dangerous = true;
3230
3231 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3232 test_Open,
3233 (void *)dcerpc_winreg_OpenHKLM_r);
3234 torture_rpc_tcase_add_test_ex(tcase, "HKU",
3235 test_Open,
3236 (void *)dcerpc_winreg_OpenHKU_r);
3237 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3238 test_Open,
3239 (void *)dcerpc_winreg_OpenHKCR_r);
3240 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3241 test_Open,
3242 (void *)dcerpc_winreg_OpenHKCU_r);
3243
3244 return suite;
3245 }
3246