Line data Source code
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 :
47 0 : static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
48 : {
49 0 : name->string = s;
50 0 : }
51 :
52 19554 : static void init_winreg_String(struct winreg_String *name, const char *s)
53 : {
54 19554 : name->name = s;
55 19554 : if (s) {
56 14922 : name->name_len = 2 * (strlen_m(s) + 1);
57 14922 : name->name_size = name->name_len;
58 : } else {
59 4632 : name->name_len = 0;
60 4632 : name->name_size = 0;
61 : }
62 19554 : }
63 :
64 348 : static bool test_GetVersion(struct dcerpc_binding_handle *b,
65 : struct torture_context *tctx,
66 : struct policy_handle *handle)
67 : {
68 0 : struct winreg_GetVersion r;
69 0 : uint32_t v;
70 :
71 348 : torture_comment(tctx, "Testing GetVersion\n");
72 :
73 348 : ZERO_STRUCT(r);
74 348 : r.in.handle = handle;
75 348 : r.out.version = &v;
76 :
77 348 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
78 : "GetVersion failed");
79 :
80 348 : torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
81 :
82 348 : return true;
83 : }
84 :
85 268 : static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
86 : struct torture_context *tctx,
87 : struct policy_handle *handle)
88 : {
89 0 : struct winreg_NotifyChangeKeyValue r;
90 :
91 268 : ZERO_STRUCT(r);
92 268 : r.in.handle = handle;
93 268 : r.in.watch_subtree = true;
94 268 : r.in.notify_filter = 0;
95 268 : r.in.unknown = r.in.unknown2 = 0;
96 268 : init_winreg_String(&r.in.string1, NULL);
97 268 : init_winreg_String(&r.in.string2, NULL);
98 :
99 268 : torture_assert_ntstatus_ok(tctx,
100 : dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
101 : "NotifyChangeKeyValue failed");
102 :
103 268 : if (!W_ERROR_IS_OK(r.out.result)) {
104 268 : torture_comment(tctx,
105 : "NotifyChangeKeyValue failed - %s - not considering\n",
106 : win_errstr(r.out.result));
107 268 : return true;
108 : }
109 :
110 0 : return true;
111 : }
112 :
113 1827 : 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 0 : struct winreg_CreateKey r;
126 0 : struct policy_handle newhandle;
127 1827 : enum winreg_CreateAction action_taken = 0;
128 :
129 1827 : torture_comment(tctx, "Testing CreateKey(%s)\n", name);
130 :
131 1827 : ZERO_STRUCT(r);
132 1827 : r.in.handle = handle;
133 1827 : init_winreg_String(&r.in.name, name);
134 1827 : init_winreg_String(&r.in.keyclass, kclass);
135 1827 : r.in.options = options;
136 1827 : r.in.access_mask = access_mask;
137 1827 : r.in.action_taken = &action_taken;
138 1827 : r.in.secdesc = secdesc;
139 1827 : r.out.new_handle = &newhandle;
140 1827 : r.out.action_taken = &action_taken;
141 :
142 1827 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
143 : "CreateKey failed");
144 :
145 1827 : torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
146 :
147 1827 : if (new_handle_p) {
148 435 : *new_handle_p = newhandle;
149 : }
150 1827 : if (action_taken_p) {
151 435 : *action_taken_p = *r.out.action_taken;
152 : }
153 :
154 1827 : return true;
155 : }
156 :
157 1392 : 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 2784 : return test_CreateKey_opts(tctx, b, handle, name, kclass,
163 : REG_OPTION_NON_VOLATILE,
164 : SEC_FLAG_MAXIMUM_ALLOWED,
165 : NULL, /* secdesc */
166 1392 : WERR_OK,
167 : NULL, /* action_taken */
168 : NULL /* new_handle */);
169 : }
170 :
171 : /*
172 : createkey testing with a SD
173 : */
174 0 : 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 0 : enum winreg_CreateAction action_taken = 0;
182 : struct security_descriptor *sd;
183 : DATA_BLOB sdblob;
184 : struct winreg_SecBuf secbuf;
185 :
186 0 : 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 0 : 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 0 : secbuf.sd.data = sdblob.data;
202 0 : secbuf.sd.len = sdblob.length;
203 0 : secbuf.sd.size = sdblob.length;
204 0 : secbuf.length = sdblob.length-10;
205 0 : secbuf.inherit = 0;
206 :
207 0 : ZERO_STRUCT(r);
208 0 : r.in.handle = handle;
209 0 : r.out.new_handle = newhandle;
210 0 : init_winreg_String(&r.in.name, name);
211 0 : init_winreg_String(&r.in.keyclass, kclass);
212 0 : r.in.options = 0x0;
213 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214 0 : r.in.action_taken = r.out.action_taken = &action_taken;
215 0 : r.in.secdesc = &secbuf;
216 :
217 0 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
218 : "CreateKey with sd failed");
219 :
220 0 : torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
221 :
222 0 : return true;
223 : }
224 :
225 0 : 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 0 : struct winreg_GetKeySecurity r;
233 0 : struct security_descriptor *sd = NULL;
234 0 : uint32_t sec_info;
235 0 : DATA_BLOB sdblob;
236 0 : struct dcerpc_binding_handle *b = p->binding_handle;
237 :
238 0 : if (sec_info_ptr) {
239 0 : sec_info = *sec_info_ptr;
240 : } else {
241 0 : sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
242 : }
243 :
244 0 : ZERO_STRUCT(r);
245 :
246 0 : r.in.handle = handle;
247 0 : r.in.sec_info = sec_info;
248 0 : r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
249 0 : r.in.sd->size = 0x1000;
250 :
251 0 : torture_assert_ntstatus_ok(tctx,
252 : dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
253 : "GetKeySecurity failed");
254 :
255 0 : torture_assert_werr_equal(tctx, r.out.result, get_werr,
256 : "GetKeySecurity failed");
257 :
258 0 : sdblob.data = r.out.sd->data;
259 0 : sdblob.length = r.out.sd->len;
260 :
261 0 : sd = talloc_zero(tctx, struct security_descriptor);
262 :
263 0 : 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 0 : if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
269 0 : NDR_PRINT_DEBUG(security_descriptor, sd);
270 : }
271 :
272 0 : if (sd_out) {
273 0 : *sd_out = sd;
274 : } else {
275 0 : talloc_free(sd);
276 : }
277 :
278 0 : return true;
279 : }
280 :
281 0 : 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 0 : return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
287 : }
288 :
289 0 : 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 0 : struct KeySecurityData *sdata = NULL;
298 : DATA_BLOB sdblob;
299 : uint32_t sec_info;
300 0 : struct dcerpc_binding_handle *b = p->binding_handle;
301 :
302 0 : ZERO_STRUCT(r);
303 :
304 0 : if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
305 0 : NDR_PRINT_DEBUG(security_descriptor, sd);
306 : }
307 :
308 0 : 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 0 : sdata = talloc_zero(tctx, struct KeySecurityData);
314 0 : sdata->data = sdblob.data;
315 0 : sdata->size = sdblob.length;
316 0 : sdata->len = sdblob.length;
317 :
318 0 : if (sec_info_ptr) {
319 0 : sec_info = *sec_info_ptr;
320 : } else {
321 0 : sec_info = SECINFO_UNPROTECTED_SACL |
322 : SECINFO_UNPROTECTED_DACL;
323 0 : if (sd->owner_sid) {
324 0 : sec_info |= SECINFO_OWNER;
325 : }
326 0 : if (sd->group_sid) {
327 0 : sec_info |= SECINFO_GROUP;
328 : }
329 0 : if (sd->sacl) {
330 0 : sec_info |= SECINFO_SACL;
331 : }
332 0 : if (sd->dacl) {
333 0 : sec_info |= SECINFO_DACL;
334 : }
335 : }
336 :
337 0 : r.in.handle = handle;
338 0 : r.in.sec_info = sec_info;
339 0 : r.in.sd = sdata;
340 :
341 0 : torture_assert_ntstatus_ok(tctx,
342 : dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
343 : "SetKeySecurity failed");
344 :
345 0 : torture_assert_werr_equal(tctx, r.out.result, werr,
346 : "SetKeySecurity failed");
347 :
348 0 : return true;
349 : }
350 :
351 0 : 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 0 : return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
357 : }
358 :
359 703 : static bool test_CloseKey(struct dcerpc_binding_handle *b,
360 : struct torture_context *tctx,
361 : struct policy_handle *handle)
362 : {
363 0 : struct winreg_CloseKey r;
364 :
365 703 : ZERO_STRUCT(r);
366 703 : r.in.handle = r.out.handle = handle;
367 :
368 703 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
369 : "CloseKey failed");
370 :
371 703 : torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
372 :
373 703 : return true;
374 : }
375 :
376 696 : static bool test_FlushKey(struct dcerpc_binding_handle *b,
377 : struct torture_context *tctx,
378 : struct policy_handle *handle)
379 : {
380 0 : struct winreg_FlushKey r;
381 :
382 696 : ZERO_STRUCT(r);
383 696 : r.in.handle = handle;
384 :
385 696 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
386 : "FlushKey failed");
387 :
388 696 : torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
389 :
390 696 : return true;
391 : }
392 :
393 804 : 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 0 : struct winreg_OpenKey r;
403 :
404 804 : ZERO_STRUCT(r);
405 804 : r.in.parent_handle = hive_handle;
406 804 : init_winreg_String(&r.in.keyname, keyname);
407 804 : r.in.options = options;
408 804 : r.in.access_mask = access_mask;
409 804 : r.out.handle = key_handle;
410 :
411 804 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
412 : "OpenKey failed");
413 :
414 804 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
415 : "OpenKey failed");
416 :
417 804 : return true;
418 : }
419 :
420 452 : 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 904 : return test_OpenKey_opts(tctx, b, hive_handle, keyname,
426 : REG_OPTION_NON_VOLATILE,
427 : SEC_FLAG_MAXIMUM_ALLOWED,
428 : key_handle,
429 452 : WERR_OK);
430 : }
431 :
432 696 : static bool test_Cleanup(struct dcerpc_binding_handle *b,
433 : struct torture_context *tctx,
434 : struct policy_handle *handle, const char *key)
435 : {
436 0 : struct winreg_DeleteKey r;
437 :
438 696 : ZERO_STRUCT(r);
439 696 : r.in.handle = handle;
440 :
441 696 : init_winreg_String(&r.in.key, key);
442 696 : dcerpc_winreg_DeleteKey_r(b, tctx, &r);
443 :
444 696 : return true;
445 : }
446 :
447 0 : 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 0 : struct security_descriptor *sd = NULL;
454 :
455 0 : if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
456 0 : return false;
457 : }
458 :
459 0 : if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
460 0 : return false;
461 : }
462 :
463 0 : return true;
464 : }
465 :
466 0 : 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 0 : bool ret = true;
473 0 : struct dcerpc_binding_handle *b = p->binding_handle;
474 :
475 0 : torture_comment(tctx, "SecurityDescriptor get & set\n");
476 :
477 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
478 0 : return false;
479 : }
480 :
481 0 : if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
482 0 : WERR_OK, WERR_OK)) {
483 0 : ret = false;
484 : }
485 :
486 0 : if (!test_CloseKey(b, tctx, &new_handle)) {
487 0 : return false;
488 : }
489 :
490 0 : return ret;
491 : }
492 :
493 0 : 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 0 : bool ret = true;
504 0 : struct dcerpc_binding_handle *b = p->binding_handle;
505 :
506 0 : 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 0 : if (!W_ERROR_IS_OK(open_werr)) {
515 0 : return true;
516 : }
517 :
518 0 : if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
519 : get_werr, set_werr)) {
520 0 : ret = false;
521 : }
522 :
523 0 : if (!test_CloseKey(b, tctx, &new_handle)) {
524 0 : return false;
525 : }
526 :
527 0 : return ret;
528 : }
529 :
530 0 : 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 0 : struct security_descriptor *sd = NULL;
536 : int i;
537 :
538 0 : if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
539 0 : return false;
540 : }
541 :
542 0 : if (!sd || !sd->dacl) {
543 0 : return false;
544 : }
545 :
546 0 : for (i = 0; i < sd->dacl->num_aces; i++) {
547 0 : if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
548 0 : return true;
549 : }
550 : }
551 :
552 0 : return false;
553 : }
554 :
555 0 : 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 0 : bool ret = true;
563 0 : struct dcerpc_binding_handle *b = p->binding_handle;
564 :
565 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
566 0 : return false;
567 : }
568 :
569 0 : ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
570 :
571 0 : test_CloseKey(b, tctx, &new_handle);
572 :
573 0 : return ret;
574 : }
575 :
576 0 : 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 0 : struct security_descriptor *sd = NULL;
582 : int i;
583 0 : uint32_t sec_info = SECINFO_SACL;
584 :
585 0 : if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
586 0 : return false;
587 : }
588 :
589 0 : if (!sd || !sd->sacl) {
590 0 : return false;
591 : }
592 :
593 0 : for (i = 0; i < sd->sacl->num_aces; i++) {
594 0 : if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
595 0 : return true;
596 : }
597 : }
598 :
599 0 : return false;
600 : }
601 :
602 0 : 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 0 : bool ret = true;
610 0 : struct dcerpc_binding_handle *b = p->binding_handle;
611 :
612 0 : 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 0 : ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
621 :
622 0 : test_CloseKey(b, tctx, &new_handle);
623 :
624 0 : return ret;
625 : }
626 :
627 0 : 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 0 : struct security_descriptor *sd = NULL;
633 0 : uint32_t sec_info = SECINFO_OWNER;
634 :
635 0 : if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
636 0 : return false;
637 : }
638 :
639 0 : if (!sd || !sd->owner_sid) {
640 0 : return false;
641 : }
642 :
643 0 : return dom_sid_equal(sd->owner_sid, sid);
644 : }
645 :
646 0 : 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 0 : bool ret = true;
654 0 : struct dcerpc_binding_handle *b = p->binding_handle;
655 :
656 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
657 0 : return false;
658 : }
659 :
660 0 : ret = test_owner_present(p, tctx, &new_handle, sid);
661 :
662 0 : test_CloseKey(b, tctx, &new_handle);
663 :
664 0 : return ret;
665 : }
666 :
667 0 : 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 0 : struct security_descriptor *sd = NULL;
673 0 : uint32_t sec_info = SECINFO_GROUP;
674 :
675 0 : if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
676 0 : return false;
677 : }
678 :
679 0 : if (!sd || !sd->group_sid) {
680 0 : return false;
681 : }
682 :
683 0 : return dom_sid_equal(sd->group_sid, sid);
684 : }
685 :
686 0 : 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 0 : bool ret = true;
694 0 : struct dcerpc_binding_handle *b = p->binding_handle;
695 :
696 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
697 0 : return false;
698 : }
699 :
700 0 : ret = test_group_present(p, tctx, &new_handle, sid);
701 :
702 0 : test_CloseKey(b, tctx, &new_handle);
703 :
704 0 : return ret;
705 : }
706 :
707 0 : 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 0 : struct security_descriptor *sd = NULL;
714 : int i;
715 :
716 0 : if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
717 0 : return false;
718 : }
719 :
720 0 : if (!sd || !sd->dacl) {
721 0 : return false;
722 : }
723 :
724 0 : for (i = 0; i < sd->dacl->num_aces; i++) {
725 0 : if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
726 0 : (sd->dacl->aces[i].flags == flags)) {
727 0 : return true;
728 : }
729 : }
730 :
731 0 : return false;
732 : }
733 :
734 0 : 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 0 : struct security_descriptor *sd = NULL;
740 : int i;
741 :
742 0 : if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
743 0 : return false;
744 : }
745 :
746 0 : if (!sd || !sd->dacl) {
747 0 : return false;
748 : }
749 :
750 0 : for (i = 0; i < sd->dacl->num_aces; i++) {
751 0 : if (security_ace_equal(&sd->dacl->aces[i], ace)) {
752 0 : return true;
753 : }
754 : }
755 :
756 0 : return false;
757 : }
758 :
759 0 : 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 0 : bool ret = true;
767 0 : struct dcerpc_binding_handle *b = p->binding_handle;
768 :
769 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
770 0 : return false;
771 : }
772 :
773 0 : if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
774 0 : ret = false;
775 : }
776 :
777 0 : if (!test_CloseKey(b, tctx, &new_handle)) {
778 0 : ret = false;
779 : }
780 :
781 0 : return ret;
782 : }
783 :
784 0 : 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 0 : bool ret = true;
792 0 : struct dcerpc_binding_handle *b = p->binding_handle;
793 :
794 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
795 0 : return false;
796 : }
797 :
798 0 : if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
799 0 : ret = false;
800 : }
801 :
802 0 : if (!test_CloseKey(b, tctx, &new_handle)) {
803 0 : ret = false;
804 : }
805 :
806 0 : return ret;
807 : }
808 :
809 0 : 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 0 : struct security_descriptor *sd = NULL;
831 0 : struct security_descriptor *sd_orig = NULL;
832 0 : struct security_ace *ace = NULL;
833 : struct policy_handle new_handle;
834 0 : bool ret = true;
835 0 : struct dcerpc_binding_handle *b = p->binding_handle;
836 : const char *test_subkey_sd;
837 : const char *test_subsubkey_sd;
838 :
839 0 : torture_comment(tctx, "SecurityDescriptor inheritance\n");
840 :
841 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
842 0 : return false;
843 : }
844 :
845 0 : if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
846 0 : return false;
847 : }
848 :
849 0 : sd_orig = security_descriptor_copy(tctx, sd);
850 0 : if (sd_orig == NULL) {
851 0 : return false;
852 : }
853 :
854 0 : 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 0 : 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 0 : sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
866 : SEC_DESC_SACL_AUTO_INHERITED;
867 :
868 0 : if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
869 0 : return false;
870 : }
871 :
872 0 : torture_assert(tctx,
873 : test_dacl_ace_present(p, tctx, &new_handle, ace),
874 : "new ACE not present!");
875 :
876 0 : if (!test_CloseKey(b, tctx, &new_handle)) {
877 0 : return false;
878 : }
879 :
880 0 : test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
881 :
882 0 : if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
883 0 : ret = false;
884 0 : goto out;
885 : }
886 :
887 0 : if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
888 0 : ret = false;
889 0 : goto out;
890 : }
891 :
892 0 : if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
893 0 : torture_comment(tctx, "inherited ACE not present!\n");
894 0 : ret = false;
895 0 : goto out;
896 : }
897 :
898 0 : test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
899 :
900 0 : test_CloseKey(b, tctx, &new_handle);
901 0 : if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
902 0 : ret = false;
903 0 : goto out;
904 : }
905 :
906 0 : if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
907 0 : ret = false;
908 0 : goto out;
909 : }
910 :
911 0 : if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
912 0 : torture_comment(tctx, "inherited ACE not present!\n");
913 0 : ret = false;
914 0 : goto out;
915 : }
916 :
917 0 : out:
918 0 : test_CloseKey(b, tctx, &new_handle);
919 0 : test_Cleanup(b, tctx, handle, test_subkey_sd);
920 0 : test_RestoreSecurity(p, tctx, handle, key, sd_orig);
921 :
922 0 : return ret;
923 : }
924 :
925 0 : 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 0 : struct security_descriptor *sd = NULL;
944 0 : struct security_descriptor *sd_orig = NULL;
945 0 : struct security_ace *ace = NULL;
946 : struct policy_handle new_handle;
947 0 : struct dom_sid *sid = NULL;
948 0 : bool ret = true;
949 0 : uint8_t ace_flags = 0x0;
950 0 : struct dcerpc_binding_handle *b = p->binding_handle;
951 : const char *test_subkey_sd;
952 : const char *test_subsubkey_sd;
953 :
954 0 : torture_comment(tctx, "SecurityDescriptor inheritance block\n");
955 :
956 0 : if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
957 0 : return false;
958 : }
959 :
960 0 : if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
961 0 : return false;
962 : }
963 :
964 0 : sd_orig = security_descriptor_copy(tctx, sd);
965 0 : if (sd_orig == NULL) {
966 0 : return false;
967 : }
968 :
969 0 : 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 0 : torture_assert_ntstatus_ok(tctx,
977 : security_descriptor_dacl_add(sd, ace),
978 : "failed to add ace");
979 :
980 0 : if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
981 0 : return false;
982 : }
983 :
984 0 : torture_assert(tctx,
985 : test_dacl_ace_present(p, tctx, &new_handle, ace),
986 : "new ACE not present!");
987 :
988 0 : if (!test_CloseKey(b, tctx, &new_handle)) {
989 0 : return false;
990 : }
991 :
992 0 : test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
993 0 : test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
994 :
995 0 : if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
996 0 : return false;
997 : }
998 :
999 0 : if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
1000 0 : ret = false;
1001 0 : goto out;
1002 : }
1003 :
1004 0 : if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1005 0 : torture_comment(tctx, "inherited ACE present but should not!\n");
1006 0 : ret = false;
1007 0 : goto out;
1008 : }
1009 :
1010 0 : sid = dom_sid_parse_talloc(tctx, TEST_SID);
1011 0 : if (sid == NULL) {
1012 0 : return false;
1013 : }
1014 :
1015 0 : if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1016 0 : torture_comment(tctx, "inherited trustee SID present but should not!\n");
1017 0 : ret = false;
1018 0 : goto out;
1019 : }
1020 :
1021 0 : test_CloseKey(b, tctx, &new_handle);
1022 :
1023 0 : if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1024 0 : ret = false;
1025 0 : goto out;
1026 : }
1027 :
1028 0 : if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1029 0 : torture_comment(tctx, "inherited ACE present but should not!\n");
1030 0 : ret = false;
1031 0 : goto out;
1032 : }
1033 :
1034 0 : if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1035 0 : torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1036 : ace_flags);
1037 0 : ret = false;
1038 0 : goto out;
1039 : }
1040 :
1041 0 : out:
1042 0 : test_CloseKey(b, tctx, &new_handle);
1043 0 : test_Cleanup(b, tctx, handle, test_subkey_sd);
1044 0 : test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1045 :
1046 0 : return ret;
1047 : }
1048 :
1049 0 : static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1050 : struct torture_context *tctx,
1051 : struct policy_handle *handle,
1052 : const char *key)
1053 : {
1054 0 : 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 0 : } 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 0 : 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 :
1109 0 : 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 0 : struct dcerpc_binding_handle *b = p->binding_handle;
1128 :
1129 0 : torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1130 : "0x%08x, access_mask: 0x%08x\n",
1131 : test, sec_info, access_mask);
1132 :
1133 0 : 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 0 : if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1142 : sd,
1143 : set_werr)) {
1144 0 : torture_warning(tctx,
1145 : "SetKeySecurity with secinfo: 0x%08x has failed\n",
1146 : sec_info);
1147 0 : smb_panic("");
1148 : test_CloseKey(b, tctx, &new_handle);
1149 : return false;
1150 : }
1151 :
1152 0 : test_CloseKey(b, tctx, &new_handle);
1153 :
1154 0 : if (W_ERROR_IS_OK(set_werr)) {
1155 : bool present;
1156 0 : present = fn(p, tctx, handle, key, sid);
1157 0 : if ((expect_present) && (!present)) {
1158 0 : torture_warning(tctx,
1159 : "%s sid is not present!\n",
1160 : test);
1161 0 : return false;
1162 : }
1163 0 : if ((!expect_present) && (present)) {
1164 0 : torture_warning(tctx,
1165 : "%s sid is present but not expected!\n",
1166 : test);
1167 0 : return false;
1168 : }
1169 : }
1170 :
1171 0 : return true;
1172 : }
1173 :
1174 0 : static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1175 : struct torture_context *tctx,
1176 : struct policy_handle *handle,
1177 : const char *key)
1178 : {
1179 0 : struct security_descriptor *sd_orig = NULL;
1180 0 : struct dom_sid *sid = NULL;
1181 0 : bool ret = true;
1182 : int i, a;
1183 :
1184 : struct security_descriptor *sd_owner =
1185 0 : security_descriptor_dacl_create(tctx,
1186 : 0,
1187 : TEST_SID, NULL, NULL);
1188 :
1189 : struct security_descriptor *sd_group =
1190 0 : security_descriptor_dacl_create(tctx,
1191 : 0,
1192 : NULL, TEST_SID, NULL);
1193 :
1194 : struct security_descriptor *sd_dacl =
1195 0 : 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 0 : 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 0 : 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 0 : uint32_t sd_owner_good_access_masks[] = {
1263 : SEC_FLAG_MAXIMUM_ALLOWED,
1264 : /* SEC_STD_WRITE_OWNER, */
1265 : };
1266 :
1267 0 : 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 0 : uint32_t sd_group_good_access_masks[] = {
1304 : SEC_FLAG_MAXIMUM_ALLOWED,
1305 : };
1306 :
1307 0 : 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 0 : uint32_t sd_dacl_good_access_masks[] = {
1343 : SEC_FLAG_MAXIMUM_ALLOWED,
1344 : SEC_STD_WRITE_DAC,
1345 : };
1346 :
1347 0 : 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 0 : uint32_t sd_sacl_good_access_masks[] = {
1384 : SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1385 : /* SEC_FLAG_SYSTEM_SECURITY, */
1386 : };
1387 :
1388 0 : sid = dom_sid_parse_talloc(tctx, TEST_SID);
1389 0 : if (sid == NULL) {
1390 0 : return false;
1391 : }
1392 :
1393 0 : if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1394 0 : return false;
1395 : }
1396 :
1397 : /* OWNER */
1398 :
1399 0 : for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1400 :
1401 0 : for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1402 :
1403 0 : 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 0 : sec_info_owner_tests[i].sid_present,
1411 : sec_info_owner_tests[i].fn,
1412 : sid))
1413 : {
1414 0 : torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1415 0 : ret = false;
1416 0 : goto out;
1417 : }
1418 : }
1419 : }
1420 :
1421 : /* GROUP */
1422 :
1423 0 : for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1424 :
1425 0 : for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1426 :
1427 0 : 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 0 : sec_info_group_tests[i].sid_present,
1435 : sec_info_group_tests[i].fn,
1436 : sid))
1437 : {
1438 0 : torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1439 0 : ret = false;
1440 0 : goto out;
1441 : }
1442 : }
1443 : }
1444 :
1445 : /* DACL */
1446 :
1447 0 : for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1448 :
1449 0 : for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1450 :
1451 0 : 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 0 : sec_info_dacl_tests[i].sid_present,
1459 : sec_info_dacl_tests[i].fn,
1460 : sid))
1461 : {
1462 0 : torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1463 0 : ret = false;
1464 0 : goto out;
1465 : }
1466 : }
1467 : }
1468 :
1469 : /* SACL */
1470 :
1471 0 : for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1472 :
1473 0 : for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1474 :
1475 0 : 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 0 : sec_info_sacl_tests[i].sid_present,
1483 : sec_info_sacl_tests[i].fn,
1484 : sid))
1485 : {
1486 0 : torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1487 0 : ret = false;
1488 0 : goto out;
1489 : }
1490 : }
1491 : }
1492 :
1493 0 : out:
1494 0 : test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1495 :
1496 0 : return ret;
1497 : }
1498 :
1499 0 : static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1500 : struct torture_context *tctx,
1501 : struct policy_handle *handle,
1502 : const char *key)
1503 : {
1504 0 : bool ret = true;
1505 :
1506 0 : if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1507 0 : torture_comment(tctx, "test_SecurityDescriptor failed\n");
1508 0 : ret = false;
1509 : }
1510 :
1511 0 : if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1512 0 : torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1513 0 : ret = false;
1514 : }
1515 :
1516 0 : if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1517 0 : torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1518 0 : ret = false;
1519 : }
1520 :
1521 0 : if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1522 0 : torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1523 0 : ret = false;
1524 : }
1525 :
1526 0 : if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1527 0 : torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1528 0 : ret = false;
1529 : }
1530 :
1531 0 : return ret;
1532 : }
1533 :
1534 2088 : 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 0 : struct winreg_DeleteKey r;
1541 :
1542 2088 : torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1543 :
1544 2088 : r.in.handle = handle;
1545 2088 : init_winreg_String(&r.in.key, key);
1546 :
1547 2088 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1548 : "Delete Key failed");
1549 2088 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
1550 : "DeleteKey failed");
1551 :
1552 2088 : return true;
1553 : }
1554 :
1555 1044 : static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1556 : struct torture_context *tctx,
1557 : struct policy_handle *handle, const char *key)
1558 : {
1559 1044 : return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1560 : }
1561 :
1562 268 : 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 0 : struct winreg_QueryInfoKey r;
1570 0 : uint32_t num_subkeys, max_subkeylen, max_classlen,
1571 : num_values, max_valnamelen, max_valbufsize,
1572 : secdescsize;
1573 0 : NTTIME last_changed_time;
1574 :
1575 268 : ZERO_STRUCT(r);
1576 268 : r.in.handle = handle;
1577 268 : r.out.num_subkeys = &num_subkeys;
1578 268 : r.out.max_subkeylen = &max_subkeylen;
1579 268 : r.out.max_classlen = &max_classlen;
1580 268 : r.out.num_values = &num_values;
1581 268 : r.out.max_valnamelen = &max_valnamelen;
1582 268 : r.out.max_valbufsize = &max_valbufsize;
1583 268 : r.out.secdescsize = &secdescsize;
1584 268 : r.out.last_changed_time = &last_changed_time;
1585 :
1586 268 : r.out.classname = talloc(tctx, struct winreg_String);
1587 :
1588 268 : r.in.classname = talloc(tctx, struct winreg_String);
1589 268 : init_winreg_String(r.in.classname, kclass);
1590 :
1591 268 : torture_assert_ntstatus_ok(tctx,
1592 : dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1593 : "QueryInfoKey failed");
1594 :
1595 268 : torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1596 :
1597 268 : if (pmax_valnamelen) {
1598 268 : *pmax_valnamelen = max_valnamelen;
1599 : }
1600 :
1601 268 : if (pmax_valbufsize) {
1602 268 : *pmax_valbufsize = max_valbufsize;
1603 : }
1604 :
1605 268 : return true;
1606 : }
1607 :
1608 3840 : 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 0 : struct winreg_SetValue r;
1617 0 : struct winreg_String name;
1618 :
1619 3840 : torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1620 : value_name, str_regtype(type), size);
1621 :
1622 3840 : init_winreg_String(&name, value_name);
1623 :
1624 3840 : r.in.handle = handle;
1625 3840 : r.in.name = name;
1626 3840 : r.in.type = type;
1627 3840 : r.in.data = data;
1628 3840 : r.in.size = size;
1629 :
1630 3840 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1631 : "winreg_SetValue failed");
1632 3840 : torture_assert_werr_ok(tctx, r.out.result,
1633 : "winreg_SetValue failed");
1634 :
1635 3840 : return true;
1636 : }
1637 :
1638 3840 : 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 0 : struct winreg_DeleteValue r;
1644 0 : struct winreg_String value;
1645 :
1646 3840 : torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1647 :
1648 3840 : init_winreg_String(&value, value_name);
1649 :
1650 3840 : r.in.handle = handle;
1651 3840 : r.in.value = value;
1652 :
1653 3840 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1654 : "winreg_DeleteValue failed");
1655 3840 : torture_assert_werr_ok(tctx, r.out.result,
1656 : "winreg_DeleteValue failed");
1657 :
1658 3840 : 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 :
1665 268 : 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 0 : struct winreg_EnumKey r;
1670 0 : struct winreg_StringBuf kclass, name;
1671 0 : NTSTATUS status;
1672 268 : NTTIME t = 0;
1673 268 : struct dcerpc_binding_handle *b = p->binding_handle;
1674 :
1675 268 : kclass.name = "";
1676 268 : kclass.size = 1024;
1677 :
1678 268 : ZERO_STRUCT(r);
1679 268 : r.in.handle = handle;
1680 268 : r.in.enum_index = 0;
1681 268 : r.in.name = &name;
1682 268 : r.in.keyclass = &kclass;
1683 268 : r.out.name = &name;
1684 268 : r.in.last_changed_time = &t;
1685 :
1686 0 : do {
1687 289 : name.name = NULL;
1688 289 : name.size = 1024;
1689 :
1690 289 : status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1691 :
1692 289 : if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1693 0 : struct policy_handle key_handle;
1694 :
1695 21 : torture_comment(tctx, "EnumKey: %d: %s\n",
1696 : r.in.enum_index,
1697 21 : r.out.name->name);
1698 :
1699 21 : if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1700 : &key_handle)) {
1701 : } else {
1702 21 : test_key(p, tctx, &key_handle,
1703 : depth + 1, test_security);
1704 : }
1705 : }
1706 :
1707 289 : r.in.enum_index++;
1708 :
1709 289 : } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1710 :
1711 268 : torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1712 :
1713 268 : if (!W_ERROR_IS_OK(r.out.result) &&
1714 268 : !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1715 0 : torture_fail(tctx, "EnumKey failed");
1716 : }
1717 :
1718 268 : return true;
1719 : }
1720 :
1721 0 : 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 0 : struct winreg_QueryMultipleValues r;
1727 0 : uint32_t bufsize=0;
1728 :
1729 0 : ZERO_STRUCT(r);
1730 :
1731 0 : r.in.key_handle = handle;
1732 0 : r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1733 0 : r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1734 0 : r.in.values_in[0].ve_valuename->name = valuename;
1735 : /* size needs to be set manually for winreg_ValNameBuf */
1736 0 : r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1737 :
1738 0 : r.in.num_values = 1;
1739 0 : r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1740 0 : *r.in.buffer_size = bufsize;
1741 0 : do {
1742 0 : *r.in.buffer_size = bufsize;
1743 0 : r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1744 : *r.in.buffer_size);
1745 :
1746 0 : torture_assert_ntstatus_ok(tctx,
1747 : dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1748 : "QueryMultipleValues failed");
1749 :
1750 0 : talloc_free(r.in.buffer);
1751 0 : bufsize += 0x20;
1752 0 : } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1753 :
1754 0 : torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1755 :
1756 0 : return true;
1757 : }
1758 :
1759 36 : 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 0 : struct winreg_QueryMultipleValues r;
1767 36 : uint32_t bufsize = 0;
1768 0 : int i;
1769 :
1770 36 : torture_comment(tctx, "Testing QueryMultipleValues\n");
1771 :
1772 36 : ZERO_STRUCT(r);
1773 :
1774 36 : r.in.key_handle = handle;
1775 36 : r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1776 36 : r.in.buffer_size = r.out.buffer_size = &bufsize;
1777 :
1778 36 : torture_assert_ntstatus_ok(tctx,
1779 : dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1780 : "QueryMultipleValues failed");
1781 36 : 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 36 : r.in.num_values = num_values;
1796 36 : r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1797 108 : for (i=0; i < r.in.num_values; i++) {
1798 72 : r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1799 72 : r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1800 72 : r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1801 : }
1802 :
1803 36 : torture_assert_ntstatus_ok(tctx,
1804 : dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1805 : "QueryMultipleValues failed");
1806 36 : torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1807 : "QueryMultipleValues failed");
1808 :
1809 36 : if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1810 20 : return true;
1811 : }
1812 :
1813 16 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1814 16 : *r.in.buffer_size = 0xff;
1815 16 : r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1816 :
1817 16 : torture_assert_ntstatus_ok(tctx,
1818 : dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1819 : "QueryMultipleValues failed");
1820 : }
1821 :
1822 16 : torture_assert_werr_ok(tctx, r.out.result,
1823 : "QueryMultipleValues failed");
1824 :
1825 16 : return true;
1826 : }
1827 :
1828 :
1829 36 : 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 0 : struct winreg_QueryMultipleValues2 r;
1837 36 : uint32_t offered = 0, needed;
1838 0 : int i;
1839 :
1840 36 : torture_comment(tctx, "Testing QueryMultipleValues2\n");
1841 :
1842 36 : ZERO_STRUCT(r);
1843 :
1844 36 : r.in.key_handle = handle;
1845 36 : r.in.offered = &offered;
1846 36 : r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1847 36 : r.out.needed = &needed;
1848 :
1849 36 : torture_assert_ntstatus_ok(tctx,
1850 : dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1851 : "QueryMultipleValues2 failed");
1852 36 : 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 36 : r.in.num_values = num_values;
1867 36 : r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1868 108 : for (i=0; i < r.in.num_values; i++) {
1869 72 : r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1870 72 : r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1871 72 : r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1872 : }
1873 :
1874 36 : torture_assert_ntstatus_ok(tctx,
1875 : dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1876 : "QueryMultipleValues2 failed");
1877 36 : torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1878 : "QueryMultipleValues2 failed");
1879 :
1880 36 : if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1881 20 : return true;
1882 : }
1883 :
1884 16 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1885 16 : *r.in.offered = *r.out.needed;
1886 16 : r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1887 :
1888 16 : torture_assert_ntstatus_ok(tctx,
1889 : dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1890 : "QueryMultipleValues2 failed");
1891 : }
1892 :
1893 16 : torture_assert_werr_ok(tctx, r.out.result,
1894 : "QueryMultipleValues2 failed");
1895 :
1896 16 : return true;
1897 : }
1898 :
1899 0 : 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 0 : struct winreg_QueryMultipleValues2 r;
1905 0 : uint32_t offered = 0, needed;
1906 :
1907 0 : ZERO_STRUCT(r);
1908 :
1909 0 : r.in.key_handle = handle;
1910 0 : r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1911 0 : r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1912 0 : r.in.values_in[0].ve_valuename->name = valuename;
1913 : /* size needs to be set manually for winreg_ValNameBuf */
1914 0 : r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1915 :
1916 0 : r.in.num_values = 1;
1917 0 : r.in.offered = &offered;
1918 0 : r.out.needed = &needed;
1919 :
1920 0 : torture_assert_ntstatus_ok(tctx,
1921 : dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1922 : "QueryMultipleValues2 failed");
1923 0 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1924 0 : *r.in.offered = *r.out.needed;
1925 0 : r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1926 :
1927 0 : torture_assert_ntstatus_ok(tctx,
1928 : dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1929 : "QueryMultipleValues2 failed");
1930 : }
1931 :
1932 0 : torture_assert_werr_ok(tctx, r.out.result,
1933 : "QueryMultipleValues2 failed");
1934 :
1935 0 : return true;
1936 : }
1937 :
1938 0 : 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 0 : struct winreg_QueryValue r;
1944 0 : NTSTATUS status;
1945 0 : enum winreg_Type zero_type = 0;
1946 0 : uint32_t offered = 0xfff;
1947 0 : uint32_t zero = 0;
1948 :
1949 0 : ZERO_STRUCT(r);
1950 0 : r.in.handle = handle;
1951 0 : r.in.data = NULL;
1952 0 : r.in.value_name = talloc_zero(tctx, struct winreg_String);
1953 0 : r.in.value_name->name = valuename;
1954 0 : r.in.type = &zero_type;
1955 0 : r.in.data_size = &offered;
1956 0 : r.in.data_length = &zero;
1957 :
1958 0 : status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1959 0 : if (NT_STATUS_IS_ERR(status)) {
1960 0 : torture_fail(tctx, "QueryValue failed");
1961 : }
1962 :
1963 0 : torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1964 :
1965 0 : return true;
1966 : }
1967 :
1968 1914 : 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 0 : struct winreg_QueryValue r;
1975 0 : struct winreg_String value_name;
1976 1914 : enum winreg_Type type = REG_NONE;
1977 1914 : uint32_t data_size = 0;
1978 1914 : uint32_t real_data_size = 0;
1979 1914 : uint32_t data_length = 0;
1980 1914 : uint8_t *data = NULL;
1981 1914 : WERROR expected_error = WERR_FILE_NOT_FOUND;
1982 1914 : const char *errmsg_nonexisting = "expected WERR_FILE_NOT_FOUND for nonexisting value";
1983 :
1984 1914 : if (valuename == NULL) {
1985 87 : expected_error = WERR_INVALID_PARAMETER;
1986 87 : errmsg_nonexisting = "expected WERR_INVALID_PARAMETER for NULL valuename";
1987 : }
1988 :
1989 1914 : ZERO_STRUCT(r);
1990 :
1991 1914 : init_winreg_String(&value_name, NULL);
1992 :
1993 1914 : torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1994 :
1995 1914 : r.in.handle = handle;
1996 1914 : r.in.value_name = &value_name;
1997 :
1998 1914 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1999 1914 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2000 : "expected WERR_INVALID_PARAMETER for NULL winreg_String.name");
2001 :
2002 1914 : init_winreg_String(&value_name, valuename);
2003 1914 : r.in.value_name = &value_name;
2004 :
2005 1914 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2006 : "QueryValue failed");
2007 1914 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2008 : "expected WERR_INVALID_PARAMETER for missing type length and size");
2009 :
2010 1914 : r.in.type = &type;
2011 1914 : r.out.type = &type;
2012 1914 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2013 : "QueryValue failed");
2014 1914 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2015 : "expected WERR_INVALID_PARAMETER for missing length and size");
2016 :
2017 1914 : r.in.data_length = &data_length;
2018 1914 : r.out.data_length = &data_length;
2019 1914 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2020 : "QueryValue failed");
2021 1914 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2022 : "expected WERR_INVALID_PARAMETER for missing size");
2023 :
2024 1914 : r.in.data_size = &data_size;
2025 1914 : r.out.data_size = &data_size;
2026 1914 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2027 : "QueryValue failed");
2028 1914 : if (existing_value) {
2029 1653 : torture_assert_werr_ok(tctx, r.out.result,
2030 : "QueryValue failed");
2031 : } else {
2032 261 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
2033 : errmsg_nonexisting);
2034 : }
2035 :
2036 1914 : real_data_size = *r.out.data_size;
2037 :
2038 1914 : data = talloc_zero_array(tctx, uint8_t, 0);
2039 1914 : r.in.data = data;
2040 1914 : r.out.data = data;
2041 1914 : *r.in.data_size = 0;
2042 1914 : *r.out.data_size = 0;
2043 1914 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2044 : "QueryValue failed");
2045 1914 : if (existing_value) {
2046 1653 : 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 261 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
2050 : errmsg_nonexisting);
2051 : }
2052 :
2053 1914 : data = talloc_zero_array(tctx, uint8_t, real_data_size);
2054 1914 : r.in.data = data;
2055 1914 : r.out.data = data;
2056 1914 : r.in.data_size = &real_data_size;
2057 1914 : r.out.data_size = &real_data_size;
2058 1914 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2059 : "QueryValue failed");
2060 1914 : if (existing_value) {
2061 1653 : torture_assert_werr_ok(tctx, r.out.result,
2062 : "QueryValue failed");
2063 : } else {
2064 261 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
2065 : errmsg_nonexisting);
2066 : }
2067 :
2068 1914 : return true;
2069 : }
2070 :
2071 529 : static bool test_EnumValue_one(struct dcerpc_binding_handle *b,
2072 : struct torture_context *tctx,
2073 : struct policy_handle *handle,
2074 : int max_valnamelen)
2075 : {
2076 0 : struct winreg_EnumValue r;
2077 529 : bool ret = true;
2078 0 : DATA_BLOB blob;
2079 :
2080 529 : blob = data_blob_string_const("data_1");
2081 529 : torture_assert_goto(tctx,
2082 : test_SetValue(b, tctx, handle, "v1", REG_BINARY, blob.data, blob.length),
2083 : ret, done,
2084 : "test_SetValue failed");
2085 :
2086 529 : blob = data_blob_string_const("data_2");
2087 529 : torture_assert_goto(tctx,
2088 : test_SetValue(b, tctx, handle, "v2", REG_BINARY, blob.data, blob.length),
2089 : ret, done,
2090 : "test_SetValue failed");
2091 :
2092 529 : ZERO_STRUCT(r);
2093 :
2094 529 : r.in.handle = handle;
2095 529 : r.in.enum_index = 0;
2096 :
2097 0 : do {
2098 1587 : enum winreg_Type type = REG_NONE;
2099 1587 : uint32_t size = 0, zero = 0;
2100 0 : struct winreg_ValNameBuf name;
2101 1587 : char n = '\0';
2102 :
2103 1587 : r.in.name = &name;
2104 1587 : r.in.type = &type;
2105 1587 : r.in.length = &zero;
2106 1587 : r.in.size = &size;
2107 1587 : r.out.name = &name;
2108 1587 : r.out.size = &size;
2109 :
2110 1587 : name.name = &n;
2111 1587 : name.size = max_valnamelen + 2;
2112 1587 : name.length = 0;
2113 :
2114 1587 : r.in.value = talloc_array(tctx, uint8_t, 0);
2115 1587 : torture_assert(tctx, r.in.value, "nomem");
2116 :
2117 1587 : torture_assert_ntstatus_ok_goto(tctx,
2118 : dcerpc_winreg_EnumValue_r(b, tctx, &r),
2119 : ret, done,
2120 : "EnumValue failed");
2121 1587 : if (W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
2122 529 : break;
2123 : }
2124 1058 : torture_assert_werr_equal_goto(tctx,
2125 : r.out.result, WERR_MORE_DATA,
2126 : ret, done,
2127 : "unexpected return code");
2128 :
2129 1058 : *r.in.size = *r.out.size;
2130 1058 : r.in.value = talloc_zero_array(tctx, uint8_t, *r.in.size);
2131 1058 : torture_assert(tctx, r.in.value, "nomem");
2132 :
2133 1058 : torture_assert_ntstatus_ok_goto(tctx,
2134 : dcerpc_winreg_EnumValue_r(b, tctx, &r),
2135 : ret, done,
2136 : "EnumValue failed");
2137 1058 : torture_assert_werr_ok_goto(tctx, r.out.result,
2138 : ret, done,
2139 : "unexpected return code");
2140 :
2141 1058 : r.in.enum_index++;
2142 :
2143 1058 : } while (W_ERROR_IS_OK(r.out.result));
2144 :
2145 529 : torture_assert_werr_equal_goto(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2146 : ret, done,
2147 : "EnumValue failed");
2148 529 : done:
2149 529 : test_DeleteValue(b, tctx, handle, "v1");
2150 529 : test_DeleteValue(b, tctx, handle, "v2");
2151 :
2152 529 : return ret;
2153 : }
2154 :
2155 536 : static bool test_EnumValue(struct dcerpc_binding_handle *b,
2156 : struct torture_context *tctx,
2157 : struct policy_handle *handle, int max_valnamelen,
2158 : int max_valbufsize)
2159 : {
2160 0 : struct winreg_EnumValue r;
2161 536 : enum winreg_Type type = 0;
2162 536 : uint32_t size = max_valbufsize, zero = 0;
2163 536 : bool ret = true;
2164 536 : uint8_t *data = NULL;
2165 0 : struct winreg_ValNameBuf name;
2166 536 : char n = '\0';
2167 :
2168 536 : ZERO_STRUCT(r);
2169 536 : r.in.handle = handle;
2170 536 : r.in.enum_index = 0;
2171 536 : r.in.name = &name;
2172 536 : r.out.name = &name;
2173 536 : r.in.type = &type;
2174 536 : r.in.length = &zero;
2175 536 : r.in.size = &size;
2176 :
2177 0 : do {
2178 536 : name.name = &n;
2179 536 : name.size = max_valnamelen + 2;
2180 536 : name.length = 0;
2181 :
2182 536 : data = NULL;
2183 536 : if (size) {
2184 268 : data = talloc_array(tctx, uint8_t, size);
2185 : }
2186 536 : r.in.value = data;
2187 :
2188 536 : torture_assert_ntstatus_ok(tctx,
2189 : dcerpc_winreg_EnumValue_r(b, tctx, &r),
2190 : "EnumValue failed");
2191 :
2192 536 : if (W_ERROR_IS_OK(r.out.result)) {
2193 0 : ret &= test_QueryValue(b, tctx, handle,
2194 0 : r.out.name->name);
2195 0 : ret &= test_QueryMultipleValues(b, tctx, handle,
2196 0 : r.out.name->name);
2197 0 : ret &= test_QueryMultipleValues2(b, tctx, handle,
2198 0 : r.out.name->name);
2199 : }
2200 :
2201 536 : talloc_free(data);
2202 :
2203 536 : r.in.enum_index++;
2204 536 : } while (W_ERROR_IS_OK(r.out.result));
2205 :
2206 536 : torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2207 : "EnumValue failed");
2208 :
2209 536 : return ret;
2210 : }
2211 :
2212 0 : static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2213 : struct torture_context *tctx)
2214 : {
2215 0 : struct winreg_AbortSystemShutdown r;
2216 0 : uint16_t server = 0x0;
2217 :
2218 0 : ZERO_STRUCT(r);
2219 0 : r.in.server = &server;
2220 :
2221 0 : torture_assert_ntstatus_ok(tctx,
2222 : dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2223 : "AbortSystemShutdown failed");
2224 :
2225 0 : torture_assert_werr_ok(tctx, r.out.result,
2226 : "AbortSystemShutdown failed");
2227 :
2228 0 : return true;
2229 : }
2230 :
2231 0 : static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2232 : struct dcerpc_pipe *p)
2233 : {
2234 0 : struct winreg_InitiateSystemShutdown r;
2235 0 : uint16_t hostname = 0x0;
2236 0 : struct dcerpc_binding_handle *b = p->binding_handle;
2237 :
2238 0 : ZERO_STRUCT(r);
2239 0 : r.in.hostname = &hostname;
2240 0 : r.in.message = talloc(tctx, struct lsa_StringLarge);
2241 0 : init_lsa_StringLarge(r.in.message, "spottyfood");
2242 0 : r.in.force_apps = 1;
2243 0 : r.in.timeout = 30;
2244 0 : r.in.do_reboot = 1;
2245 :
2246 0 : torture_assert_ntstatus_ok(tctx,
2247 : dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2248 : "InitiateSystemShutdown failed");
2249 :
2250 0 : torture_assert_werr_ok(tctx, r.out.result,
2251 : "InitiateSystemShutdown failed");
2252 :
2253 0 : return test_AbortSystemShutdown(b, tctx);
2254 : }
2255 :
2256 :
2257 0 : static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2258 : struct dcerpc_pipe *p)
2259 : {
2260 0 : struct winreg_InitiateSystemShutdownEx r;
2261 0 : uint16_t hostname = 0x0;
2262 0 : struct dcerpc_binding_handle *b = p->binding_handle;
2263 :
2264 0 : ZERO_STRUCT(r);
2265 0 : r.in.hostname = &hostname;
2266 0 : r.in.message = talloc(tctx, struct lsa_StringLarge);
2267 0 : init_lsa_StringLarge(r.in.message, "spottyfood");
2268 0 : r.in.force_apps = 1;
2269 0 : r.in.timeout = 30;
2270 0 : r.in.do_reboot = 1;
2271 0 : r.in.reason = 0;
2272 :
2273 0 : torture_assert_ntstatus_ok(tctx,
2274 : dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2275 : "InitiateSystemShutdownEx failed");
2276 :
2277 0 : torture_assert_werr_ok(tctx, r.out.result,
2278 : "InitiateSystemShutdownEx failed");
2279 :
2280 0 : return test_AbortSystemShutdown(b, tctx);
2281 : }
2282 : #define MAX_DEPTH 2 /* Only go this far down the tree */
2283 :
2284 282 : static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2285 : struct policy_handle *handle, int depth,
2286 : bool test_security)
2287 : {
2288 282 : struct dcerpc_binding_handle *b = p->binding_handle;
2289 282 : uint32_t max_valnamelen = 0;
2290 282 : uint32_t max_valbufsize = 0;
2291 :
2292 282 : if (depth == MAX_DEPTH)
2293 14 : return true;
2294 :
2295 268 : if (!test_QueryInfoKey(b, tctx, handle, NULL,
2296 : &max_valnamelen, &max_valbufsize)) {
2297 0 : }
2298 :
2299 268 : if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2300 0 : }
2301 :
2302 268 : if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2303 0 : }
2304 :
2305 268 : if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2306 0 : }
2307 :
2308 268 : if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2309 0 : }
2310 :
2311 268 : if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2312 0 : }
2313 :
2314 268 : if (!test_EnumValue_one(b, tctx, handle, 0xff)) {
2315 0 : return false;
2316 : }
2317 :
2318 268 : test_CloseKey(b, tctx, handle);
2319 :
2320 268 : return true;
2321 : }
2322 :
2323 87 : static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2324 : struct torture_context *tctx,
2325 : struct policy_handle *handle)
2326 : {
2327 87 : const char *value_name = TEST_VALUE;
2328 87 : uint32_t value = 0x12345678;
2329 87 : uint64_t value2 = 0x12345678;
2330 87 : const char *string = "torture";
2331 0 : const char *array[2];
2332 0 : DATA_BLOB blob;
2333 87 : enum winreg_Type types[] = {
2334 : REG_DWORD,
2335 : REG_DWORD_BIG_ENDIAN,
2336 : REG_QWORD,
2337 : REG_BINARY,
2338 : REG_SZ,
2339 : REG_MULTI_SZ
2340 : };
2341 0 : int t;
2342 :
2343 87 : array[0] = "array0";
2344 87 : array[1] = NULL;
2345 :
2346 87 : torture_comment(tctx, "Testing SetValue (standard formats)\n");
2347 :
2348 609 : for (t=0; t < ARRAY_SIZE(types); t++) {
2349 :
2350 0 : enum winreg_Type w_type;
2351 0 : uint32_t w_size, w_length;
2352 0 : uint8_t *w_data;
2353 :
2354 522 : switch (types[t]) {
2355 174 : case REG_DWORD:
2356 : case REG_DWORD_BIG_ENDIAN:
2357 174 : blob = data_blob_talloc_zero(tctx, 4);
2358 174 : SIVAL(blob.data, 0, value);
2359 174 : break;
2360 87 : case REG_QWORD:
2361 87 : blob = data_blob_talloc_zero(tctx, 8);
2362 87 : SBVAL(blob.data, 0, value2);
2363 87 : break;
2364 87 : case REG_BINARY:
2365 87 : blob = data_blob_string_const("binary_blob");
2366 87 : break;
2367 87 : case REG_SZ:
2368 87 : torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2369 87 : break;
2370 87 : case REG_MULTI_SZ:
2371 87 : torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2372 87 : break;
2373 0 : default:
2374 0 : break;
2375 : }
2376 :
2377 522 : torture_assert(tctx,
2378 : test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2379 : "test_SetValue failed");
2380 522 : torture_assert(tctx,
2381 : test_QueryValue_full(b, tctx, handle, value_name, true),
2382 : talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2383 522 : torture_assert(tctx,
2384 : test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2385 : "test_winreg_QueryValue failed");
2386 522 : torture_assert(tctx,
2387 : test_DeleteValue(b, tctx, handle, value_name),
2388 : "test_DeleteValue failed");
2389 :
2390 522 : torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2391 522 : torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2392 522 : torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2393 522 : torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2394 : }
2395 :
2396 87 : torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2397 :
2398 87 : return true;
2399 : }
2400 :
2401 87 : static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2402 : struct torture_context *tctx,
2403 : struct policy_handle *handle)
2404 : {
2405 0 : DATA_BLOB blob;
2406 87 : const char *values[] = {
2407 : "torture_value",
2408 : "torture value",
2409 : "torture,value",
2410 : "torture;value",
2411 : "torture/value",
2412 : "torture\\value",
2413 : "torture_value_name",
2414 : "torture value name",
2415 : "torture,value,name",
2416 : "torture;value;name",
2417 : "torture/value/name",
2418 : "torture\\value\\name",
2419 : };
2420 0 : int i;
2421 :
2422 87 : torture_comment(tctx, "Testing SetValue (values)\n");
2423 :
2424 1131 : for (i=0; i < ARRAY_SIZE(values); i++) {
2425 :
2426 0 : enum winreg_Type w_type;
2427 0 : uint32_t w_size, w_length;
2428 0 : uint8_t *w_data;
2429 :
2430 1044 : blob = data_blob_talloc(tctx, NULL, 32);
2431 :
2432 1044 : generate_random_buffer(blob.data, 32);
2433 :
2434 1044 : torture_assert(tctx,
2435 : test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2436 : "test_SetValue failed");
2437 1044 : torture_assert(tctx,
2438 : test_QueryValue_full(b, tctx, handle, values[i], true),
2439 : talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2440 1044 : torture_assert(tctx,
2441 : test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2442 : "test_winreg_QueryValue failed");
2443 1044 : torture_assert(tctx,
2444 : test_DeleteValue(b, tctx, handle, values[i]),
2445 : "test_DeleteValue failed");
2446 :
2447 1044 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2448 1044 : torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2449 1044 : torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2450 1044 : torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2451 : }
2452 :
2453 87 : torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2454 :
2455 87 : return true;
2456 : }
2457 :
2458 : typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2459 :
2460 87 : static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2461 : struct torture_context *tctx,
2462 : struct policy_handle *handle)
2463 : {
2464 87 : const char *value_name = TEST_VALUE;
2465 87 : enum winreg_Type types[] = {
2466 : REG_NONE,
2467 : REG_SZ,
2468 : REG_EXPAND_SZ,
2469 : REG_BINARY,
2470 : REG_DWORD,
2471 : REG_DWORD_BIG_ENDIAN,
2472 : REG_LINK,
2473 : REG_MULTI_SZ,
2474 : REG_RESOURCE_LIST,
2475 : REG_FULL_RESOURCE_DESCRIPTOR,
2476 : REG_RESOURCE_REQUIREMENTS_LIST,
2477 : REG_QWORD,
2478 : 12,
2479 : 13,
2480 : 14,
2481 : 55,
2482 : 123456,
2483 : 653210,
2484 : __LINE__
2485 : };
2486 0 : int t, l;
2487 :
2488 87 : if (torture_setting_bool(tctx, "samba4", false)) {
2489 83 : torture_skip(tctx, "skipping extended SetValue test against Samba4");
2490 : }
2491 :
2492 4 : torture_comment(tctx, "Testing SetValue (extended formats)\n");
2493 :
2494 80 : for (t=0; t < ARRAY_SIZE(types); t++) {
2495 1292 : for (l=0; l < 16; l++) {
2496 :
2497 0 : enum winreg_Type w_type;
2498 0 : uint32_t w_size, w_length;
2499 0 : uint8_t *w_data;
2500 :
2501 0 : uint32_t size;
2502 0 : uint8_t *data;
2503 :
2504 1216 : size = l;
2505 1216 : data = talloc_array(tctx, uint8_t, size);
2506 :
2507 1216 : generate_random_buffer(data, size);
2508 :
2509 1216 : torture_assert(tctx,
2510 : test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2511 : "test_SetValue failed");
2512 :
2513 1216 : torture_assert(tctx,
2514 : test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2515 : "test_winreg_QueryValue failed");
2516 :
2517 1216 : torture_assert(tctx,
2518 : test_DeleteValue(b, tctx, handle, value_name),
2519 : "test_DeleteValue failed");
2520 :
2521 1216 : torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2522 1216 : torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2523 1216 : torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2524 1216 : torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2525 : }
2526 : }
2527 :
2528 4 : torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2529 :
2530 4 : return true;
2531 : }
2532 :
2533 87 : static bool test_create_keynames(struct dcerpc_binding_handle *b,
2534 : struct torture_context *tctx,
2535 : struct policy_handle *handle)
2536 : {
2537 87 : const char *keys[] = {
2538 : "torture_key",
2539 : "torture key",
2540 : "torture,key",
2541 : "torture/key",
2542 : "torture\\key",
2543 : };
2544 0 : int i;
2545 :
2546 522 : for (i=0; i < ARRAY_SIZE(keys); i++) {
2547 :
2548 0 : enum winreg_CreateAction action_taken;
2549 0 : struct policy_handle new_handle;
2550 0 : char *q, *tmp;
2551 :
2552 435 : torture_assert(tctx,
2553 : test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2554 : REG_OPTION_NON_VOLATILE,
2555 : SEC_FLAG_MAXIMUM_ALLOWED,
2556 : NULL,
2557 : WERR_OK,
2558 : &action_taken,
2559 : &new_handle),
2560 : talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2561 :
2562 435 : torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2563 :
2564 435 : torture_assert(tctx,
2565 : test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2566 : "failed to delete key");
2567 :
2568 435 : torture_assert(tctx,
2569 : test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_FILE_NOT_FOUND),
2570 : "failed 2nd delete key");
2571 :
2572 435 : tmp = talloc_strdup(tctx, keys[i]);
2573 :
2574 435 : q = strchr(tmp, '\\');
2575 435 : if (q != NULL) {
2576 87 : *q = '\0';
2577 87 : q++;
2578 :
2579 87 : torture_assert(tctx,
2580 : test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2581 : "failed to delete key");
2582 :
2583 87 : torture_assert(tctx,
2584 : test_DeleteKey_opts(b, tctx, handle, tmp, WERR_FILE_NOT_FOUND),
2585 : "failed 2nd delete key");
2586 : }
2587 : }
2588 :
2589 87 : return true;
2590 : }
2591 :
2592 : #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2593 : #define VALUE_CURRENT_VERSION "CurrentVersion"
2594 : #define VALUE_SYSTEM_ROOT "SystemRoot"
2595 :
2596 : static const struct {
2597 : const char *values[3];
2598 : uint32_t num_values;
2599 : bool existing_value;
2600 : const char *error_message;
2601 : } multiple_values_tests[] = {
2602 : {
2603 : .values = { VALUE_CURRENT_VERSION, NULL, NULL },
2604 : .num_values = 1,
2605 : .existing_value = true,
2606 : .error_message = NULL
2607 : },{
2608 : .values = { VALUE_SYSTEM_ROOT, NULL, NULL },
2609 : .num_values = 1,
2610 : .existing_value = true,
2611 : .error_message = NULL
2612 : },{
2613 : .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT, NULL },
2614 : .num_values = 2,
2615 : .existing_value = true,
2616 : .error_message = NULL
2617 : },{
2618 : .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT,
2619 : VALUE_CURRENT_VERSION },
2620 : .num_values = 3,
2621 : .existing_value = true,
2622 : .error_message = NULL
2623 : },{
2624 : .values = { VALUE_CURRENT_VERSION, NULL, VALUE_SYSTEM_ROOT },
2625 : .num_values = 3,
2626 : .existing_value = false,
2627 : .error_message = NULL
2628 : },{
2629 : .values = { VALUE_CURRENT_VERSION, "", VALUE_SYSTEM_ROOT },
2630 : .num_values = 3,
2631 : .existing_value = false,
2632 : .error_message = NULL
2633 : },{
2634 : .values = { "IDoNotExist", NULL, NULL },
2635 : .num_values = 1,
2636 : .existing_value = false,
2637 : .error_message = NULL
2638 : },{
2639 : .values = { "IDoNotExist", VALUE_CURRENT_VERSION, NULL },
2640 : .num_values = 2,
2641 : .existing_value = false,
2642 : .error_message = NULL
2643 : },{
2644 : .values = { VALUE_CURRENT_VERSION, "IDoNotExist", NULL },
2645 : .num_values = 2,
2646 : .existing_value = false,
2647 : .error_message = NULL
2648 : }
2649 : };
2650 :
2651 87 : static bool test_HKLM_wellknown(struct torture_context *tctx,
2652 : struct dcerpc_binding_handle *b,
2653 : struct policy_handle *handle)
2654 : {
2655 0 : struct policy_handle newhandle;
2656 0 : int i;
2657 :
2658 : /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2659 87 : if (torture_setting_bool(tctx, "samba3", false)) {
2660 4 : torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2661 : KEY_CURRENT_VERSION,
2662 : REG_OPTION_NON_VOLATILE,
2663 : KEY_QUERY_VALUE,
2664 : &newhandle,
2665 : WERR_OK),
2666 : "failed to open current version key");
2667 : } else {
2668 83 : torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2669 : "failed to open current version key");
2670 : }
2671 :
2672 87 : torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2673 : "failed to query current version");
2674 87 : torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2675 : "succeeded to query nonexistent value");
2676 87 : torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2677 : "succeeded to query value with NULL name");
2678 87 : torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2679 : "succeeded to query nonexistent default value (\"\")");
2680 :
2681 87 : if (torture_setting_bool(tctx, "samba4", false)) {
2682 83 : torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2683 83 : goto close_key;
2684 : }
2685 :
2686 40 : for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2687 0 : const char *msg;
2688 36 : msg = talloc_asprintf(tctx,
2689 : "failed to query %d %sexisting values\n",
2690 36 : multiple_values_tests[i].num_values,
2691 36 : multiple_values_tests[i].existing_value ? "":"non");
2692 :
2693 36 : torture_assert(tctx,
2694 : test_QueryMultipleValues_full(b, tctx, &newhandle,
2695 : multiple_values_tests[i].num_values,
2696 : multiple_values_tests[i].values,
2697 : multiple_values_tests[i].existing_value),
2698 : msg);
2699 36 : torture_assert(tctx,
2700 : test_QueryMultipleValues2_full(b, tctx, &newhandle,
2701 : multiple_values_tests[i].num_values,
2702 : multiple_values_tests[i].values,
2703 : multiple_values_tests[i].existing_value),
2704 : msg);
2705 : }
2706 :
2707 4 : close_key:
2708 87 : torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2709 : "failed to close current version key");
2710 :
2711 87 : return true;
2712 : }
2713 :
2714 0 : static bool test_OpenHive(struct torture_context *tctx,
2715 : struct dcerpc_binding_handle *b,
2716 : struct policy_handle *handle,
2717 : int hkey)
2718 : {
2719 0 : struct winreg_OpenHKLM r;
2720 :
2721 0 : r.in.system_name = 0;
2722 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2723 0 : r.out.handle = handle;
2724 :
2725 0 : switch (hkey) {
2726 0 : case HKEY_LOCAL_MACHINE:
2727 0 : torture_assert_ntstatus_ok(tctx,
2728 : dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2729 : "failed to open HKLM");
2730 0 : torture_assert_werr_ok(tctx, r.out.result,
2731 : "failed to open HKLM");
2732 0 : break;
2733 0 : case HKEY_CURRENT_USER:
2734 0 : torture_assert_ntstatus_ok(tctx,
2735 : dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2736 : "failed to open HKCU");
2737 0 : torture_assert_werr_ok(tctx, r.out.result,
2738 : "failed to open HKCU");
2739 0 : break;
2740 0 : case HKEY_USERS:
2741 0 : torture_assert_ntstatus_ok(tctx,
2742 : dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2743 : "failed to open HKU");
2744 0 : torture_assert_werr_ok(tctx, r.out.result,
2745 : "failed to open HKU");
2746 0 : break;
2747 0 : case HKEY_CLASSES_ROOT:
2748 0 : torture_assert_ntstatus_ok(tctx,
2749 : dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2750 : "failed to open HKCR");
2751 0 : torture_assert_werr_ok(tctx, r.out.result,
2752 : "failed to open HKCR");
2753 0 : break;
2754 0 : default:
2755 0 : torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2756 0 : return false;
2757 : }
2758 :
2759 0 : return true;
2760 : }
2761 :
2762 0 : static bool test_volatile_keys(struct torture_context *tctx,
2763 : struct dcerpc_binding_handle *b,
2764 : struct policy_handle *handle,
2765 : int hkey)
2766 : {
2767 0 : struct policy_handle new_handle, hive_handle;
2768 0 : enum winreg_CreateAction action_taken = REG_ACTION_NONE;
2769 :
2770 0 : ZERO_STRUCT(new_handle);
2771 0 : ZERO_STRUCT(hive_handle);
2772 :
2773 0 : torture_comment(tctx, "Testing VOLATILE key\n");
2774 :
2775 0 : test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2776 :
2777 0 : torture_assert(tctx,
2778 : test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2779 : REG_OPTION_VOLATILE,
2780 : SEC_FLAG_MAXIMUM_ALLOWED,
2781 : NULL,
2782 : WERR_OK,
2783 : &action_taken,
2784 : &new_handle),
2785 : "failed to create REG_OPTION_VOLATILE type key");
2786 :
2787 0 : torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2788 :
2789 0 : torture_assert(tctx,
2790 : test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2791 : REG_OPTION_NON_VOLATILE,
2792 : SEC_FLAG_MAXIMUM_ALLOWED,
2793 : NULL,
2794 : WERR_CHILD_MUST_BE_VOLATILE,
2795 : NULL,
2796 : NULL),
2797 : "failed to fail create REG_OPTION_VOLATILE type key");
2798 :
2799 0 : torture_assert(tctx,
2800 : test_CloseKey(b, tctx, &new_handle),
2801 : "failed to close");
2802 :
2803 0 : torture_assert(tctx,
2804 : test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2805 : REG_OPTION_NON_VOLATILE,
2806 : SEC_FLAG_MAXIMUM_ALLOWED,
2807 : &new_handle,
2808 : WERR_OK),
2809 : "failed to open volatile key");
2810 :
2811 0 : torture_assert(tctx,
2812 : test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2813 : "failed to delete key");
2814 :
2815 0 : torture_assert(tctx,
2816 : test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2817 : REG_OPTION_VOLATILE,
2818 : SEC_FLAG_MAXIMUM_ALLOWED,
2819 : NULL,
2820 : WERR_OK,
2821 : &action_taken,
2822 : &new_handle),
2823 : "failed to create REG_OPTION_VOLATILE type key");
2824 :
2825 0 : torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2826 :
2827 0 : torture_assert(tctx,
2828 : test_CloseKey(b, tctx, &new_handle),
2829 : "failed to close");
2830 :
2831 0 : torture_assert(tctx,
2832 : test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2833 : REG_OPTION_VOLATILE,
2834 : SEC_FLAG_MAXIMUM_ALLOWED,
2835 : &new_handle,
2836 : WERR_OK),
2837 : "failed to open volatile key");
2838 :
2839 0 : torture_assert(tctx,
2840 : test_CloseKey(b, tctx, &new_handle),
2841 : "failed to close");
2842 :
2843 0 : torture_assert(tctx,
2844 : test_OpenHive(tctx, b, &hive_handle, hkey),
2845 : "failed top open hive");
2846 :
2847 0 : torture_assert(tctx,
2848 : test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2849 : REG_OPTION_VOLATILE,
2850 : SEC_FLAG_MAXIMUM_ALLOWED,
2851 : &new_handle,
2852 : WERR_FILE_NOT_FOUND),
2853 : "failed to open volatile key");
2854 :
2855 0 : torture_assert(tctx,
2856 : test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2857 : REG_OPTION_NON_VOLATILE,
2858 : SEC_FLAG_MAXIMUM_ALLOWED,
2859 : &new_handle,
2860 : WERR_FILE_NOT_FOUND),
2861 : "failed to open volatile key");
2862 :
2863 0 : torture_assert(tctx,
2864 : test_CloseKey(b, tctx, &hive_handle),
2865 : "failed to close");
2866 :
2867 0 : torture_assert(tctx,
2868 : test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2869 : "failed to delete key");
2870 :
2871 :
2872 0 : torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2873 :
2874 0 : return true;
2875 : }
2876 :
2877 0 : static const char *kernel_mode_registry_path(struct torture_context *tctx,
2878 : int hkey,
2879 : const char *sid_string,
2880 : const char *path)
2881 : {
2882 0 : switch (hkey) {
2883 0 : case HKEY_LOCAL_MACHINE:
2884 0 : return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2885 0 : case HKEY_CURRENT_USER:
2886 0 : return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2887 0 : case HKEY_USERS:
2888 0 : return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2889 0 : case HKEY_CLASSES_ROOT:
2890 0 : return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2891 0 : default:
2892 0 : torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2893 0 : return NULL;
2894 : }
2895 : }
2896 :
2897 0 : static bool test_symlink_keys(struct torture_context *tctx,
2898 : struct dcerpc_binding_handle *b,
2899 : struct policy_handle *handle,
2900 : const char *key,
2901 : int hkey)
2902 : {
2903 0 : struct policy_handle new_handle;
2904 0 : enum winreg_CreateAction action_taken;
2905 0 : DATA_BLOB blob;
2906 0 : uint32_t value = 42;
2907 0 : const char *test_key_symlink_dest;
2908 0 : const char *test_key_symlink;
2909 0 : const char *kernel_mode_path;
2910 :
2911 : /* disable until we know how to delete a symbolic link */
2912 0 : torture_skip(tctx, "symlink test disabled");
2913 :
2914 : torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2915 :
2916 : /* create destination key with testvalue */
2917 : test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2918 : key, TEST_KEY_SYMLINK);
2919 : test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2920 : key, TEST_KEY_SYMLINK_DEST);
2921 :
2922 : test_DeleteKey(b, tctx, handle, test_key_symlink);
2923 :
2924 : torture_assert(tctx,
2925 : test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2926 : 0,
2927 : SEC_FLAG_MAXIMUM_ALLOWED,
2928 : NULL,
2929 : WERR_OK,
2930 : &action_taken,
2931 : &new_handle),
2932 : "failed to create symlink destination");
2933 :
2934 : blob = data_blob_talloc_zero(tctx, 4);
2935 : SIVAL(blob.data, 0, value);
2936 :
2937 : torture_assert(tctx,
2938 : test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2939 : "failed to create TestValue");
2940 :
2941 : torture_assert(tctx,
2942 : test_CloseKey(b, tctx, &new_handle),
2943 : "failed to close");
2944 :
2945 : /* create symlink */
2946 :
2947 : torture_assert(tctx,
2948 : test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2949 : REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2950 : SEC_FLAG_MAXIMUM_ALLOWED,
2951 : NULL,
2952 : WERR_OK,
2953 : &action_taken,
2954 : &new_handle),
2955 : "failed to create REG_OPTION_CREATE_LINK type key");
2956 :
2957 : torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2958 :
2959 : kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2960 :
2961 : torture_assert(tctx,
2962 : convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2963 : kernel_mode_path,
2964 : strlen(kernel_mode_path), /* not NULL terminated */
2965 : &blob.data, &blob.length),
2966 : "failed to convert");
2967 :
2968 : torture_assert(tctx,
2969 : test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2970 : "failed to create SymbolicLinkValue value");
2971 :
2972 : torture_assert(tctx,
2973 : test_CloseKey(b, tctx, &new_handle),
2974 : "failed to close");
2975 :
2976 : /* test follow symlink */
2977 :
2978 : torture_assert(tctx,
2979 : test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2980 : 0,
2981 : SEC_FLAG_MAXIMUM_ALLOWED,
2982 : &new_handle,
2983 : WERR_OK),
2984 : "failed to follow symlink key");
2985 :
2986 : torture_assert(tctx,
2987 : test_QueryValue(b, tctx, &new_handle, "TestValue"),
2988 : "failed to query value");
2989 :
2990 : torture_assert(tctx,
2991 : test_CloseKey(b, tctx, &new_handle),
2992 : "failed to close");
2993 :
2994 : /* delete link */
2995 :
2996 : torture_assert(tctx,
2997 : test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2998 : REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2999 : SEC_FLAG_MAXIMUM_ALLOWED,
3000 : &new_handle,
3001 : WERR_OK),
3002 : "failed to open symlink key");
3003 :
3004 : torture_assert(tctx,
3005 : test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
3006 : "failed to delete value SymbolicLinkValue");
3007 :
3008 : torture_assert(tctx,
3009 : test_CloseKey(b, tctx, &new_handle),
3010 : "failed to close");
3011 :
3012 : torture_assert(tctx,
3013 : test_DeleteKey(b, tctx, handle, test_key_symlink),
3014 : "failed to delete key");
3015 :
3016 : /* delete destination */
3017 :
3018 : torture_assert(tctx,
3019 : test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
3020 : "failed to delete key");
3021 :
3022 : return true;
3023 : }
3024 :
3025 261 : static bool test_CreateKey_keytypes(struct torture_context *tctx,
3026 : struct dcerpc_binding_handle *b,
3027 : struct policy_handle *handle,
3028 : const char *key,
3029 : int hkey)
3030 : {
3031 :
3032 510 : if (torture_setting_bool(tctx, "samba3", false) ||
3033 249 : torture_setting_bool(tctx, "samba4", false)) {
3034 261 : torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
3035 : }
3036 :
3037 0 : torture_assert(tctx,
3038 : test_volatile_keys(tctx, b, handle, hkey),
3039 : "failed to test volatile keys");
3040 :
3041 0 : torture_assert(tctx,
3042 : test_symlink_keys(tctx, b, handle, key, hkey),
3043 : "failed to test symlink keys");
3044 :
3045 0 : return true;
3046 : }
3047 :
3048 348 : static bool test_key_base(struct torture_context *tctx,
3049 : struct dcerpc_binding_handle *b,
3050 : struct policy_handle *handle,
3051 : const char *base_key,
3052 : int hkey)
3053 : {
3054 0 : struct policy_handle newhandle;
3055 348 : bool ret = true, created = false, deleted = false;
3056 348 : bool created3 = false;
3057 0 : const char *test_key1;
3058 0 : const char *test_key3;
3059 0 : const char *test_subkey;
3060 :
3061 348 : test_Cleanup(b, tctx, handle, base_key);
3062 :
3063 348 : if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
3064 0 : torture_comment(tctx,
3065 : "CreateKey(%s) failed\n", base_key);
3066 : }
3067 :
3068 348 : test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
3069 :
3070 348 : if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
3071 0 : torture_comment(tctx,
3072 : "CreateKey failed - not considering a failure\n");
3073 : } else {
3074 348 : created = true;
3075 : }
3076 :
3077 348 : if (created) {
3078 348 : if (!test_FlushKey(b, tctx, handle)) {
3079 0 : torture_comment(tctx, "FlushKey failed\n");
3080 0 : ret = false;
3081 : }
3082 :
3083 348 : if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
3084 0 : torture_fail(tctx,
3085 : "CreateKey failed (OpenKey after Create didn't work)\n");
3086 : }
3087 :
3088 348 : if (hkey == HKEY_CURRENT_USER) {
3089 87 : torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
3090 : "simple SetValue test failed");
3091 87 : torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
3092 : "values SetValue test failed");
3093 87 : torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
3094 : "extended SetValue test failed");
3095 87 : torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
3096 : "keyname CreateKey test failed");
3097 : } else {
3098 261 : torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
3099 : "keytype test failed");
3100 261 : torture_assert(tctx, test_EnumValue_one(b, tctx, &newhandle, 0xff),
3101 : "simple EnumValue test failed");
3102 : }
3103 :
3104 348 : if (!test_CloseKey(b, tctx, &newhandle)) {
3105 0 : torture_fail(tctx,
3106 : "CreateKey failed (CloseKey after Open didn't work)\n");
3107 : }
3108 :
3109 348 : if (!test_DeleteKey(b, tctx, handle, test_key1)) {
3110 0 : torture_comment(tctx, "DeleteKey(%s) failed\n",
3111 : test_key1);
3112 0 : ret = false;
3113 : } else {
3114 348 : deleted = true;
3115 : }
3116 :
3117 348 : if (!test_FlushKey(b, tctx, handle)) {
3118 0 : torture_comment(tctx, "FlushKey failed\n");
3119 0 : ret = false;
3120 : }
3121 :
3122 348 : if (deleted) {
3123 348 : if (!test_OpenKey_opts(tctx, b, handle, test_key1,
3124 : REG_OPTION_NON_VOLATILE,
3125 : SEC_FLAG_MAXIMUM_ALLOWED,
3126 : &newhandle,
3127 348 : WERR_FILE_NOT_FOUND)) {
3128 0 : torture_comment(tctx,
3129 : "DeleteKey failed (OpenKey after Delete "
3130 : "did not return WERR_FILE_NOT_FOUND)\n");
3131 0 : ret = false;
3132 : }
3133 : }
3134 :
3135 348 : test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
3136 :
3137 348 : if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
3138 348 : created3 = true;
3139 : }
3140 :
3141 348 : test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
3142 :
3143 348 : if (created3) {
3144 348 : if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
3145 348 : if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
3146 0 : torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
3147 0 : ret = false;
3148 : }
3149 : }
3150 :
3151 348 : if (!test_DeleteKey(b, tctx, handle, test_key3)) {
3152 0 : torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
3153 0 : ret = false;
3154 : }
3155 : }
3156 : }
3157 :
3158 348 : test_Cleanup(b, tctx, handle, base_key);
3159 :
3160 348 : return ret;
3161 : }
3162 :
3163 348 : static bool test_key_base_sd(struct torture_context *tctx,
3164 : struct dcerpc_pipe *p,
3165 : struct policy_handle *handle,
3166 : const char *base_key)
3167 : {
3168 0 : struct policy_handle newhandle;
3169 348 : bool ret = true, created2 = false, created4 = false;
3170 348 : struct dcerpc_binding_handle *b = p->binding_handle;
3171 0 : const char *test_key2;
3172 0 : const char *test_key4;
3173 :
3174 348 : torture_skip(tctx, "security descriptor test disabled\n");
3175 :
3176 : if (torture_setting_bool(tctx, "samba3", false) ||
3177 : torture_setting_bool(tctx, "samba4", false)) {
3178 : torture_skip(tctx, "skipping security descriptor tests against Samba");
3179 : }
3180 :
3181 : test_Cleanup(b, tctx, handle, base_key);
3182 :
3183 : if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
3184 : torture_comment(tctx,
3185 : "CreateKey(%s) failed\n", base_key);
3186 : }
3187 :
3188 : test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
3189 :
3190 : if (test_CreateKey_sd(b, tctx, handle, test_key2,
3191 : NULL, &newhandle)) {
3192 : created2 = true;
3193 : }
3194 :
3195 : if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3196 : torture_comment(tctx, "CloseKey failed\n");
3197 : ret = false;
3198 : }
3199 :
3200 : test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3201 :
3202 : if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3203 : created4 = true;
3204 : }
3205 :
3206 : if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3207 : torture_comment(tctx, "CloseKey failed\n");
3208 : ret = false;
3209 : }
3210 :
3211 : if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3212 : ret = false;
3213 : }
3214 :
3215 : if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3216 : torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3217 : ret = false;
3218 : }
3219 :
3220 : if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3221 : torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3222 : ret = false;
3223 : }
3224 :
3225 : test_Cleanup(b, tctx, handle, base_key);
3226 :
3227 : return ret;
3228 : }
3229 :
3230 348 : static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3231 : void *userdata)
3232 : {
3233 0 : struct policy_handle handle;
3234 348 : bool ret = true;
3235 0 : struct winreg_OpenHKLM r;
3236 348 : struct dcerpc_binding_handle *b = p->binding_handle;
3237 0 : const char *torture_base_key;
3238 348 : int hkey = 0;
3239 :
3240 348 : winreg_open_fn open_fn = (winreg_open_fn)userdata;
3241 :
3242 348 : r.in.system_name = 0;
3243 348 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3244 348 : r.out.handle = &handle;
3245 :
3246 348 : torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3247 : "open");
3248 :
3249 348 : if (!test_GetVersion(b, tctx, &handle)) {
3250 0 : torture_comment(tctx, "GetVersion failed\n");
3251 0 : ret = false;
3252 : }
3253 :
3254 348 : if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3255 87 : hkey = HKEY_LOCAL_MACHINE;
3256 87 : torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3257 261 : } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3258 87 : hkey = HKEY_USERS;
3259 87 : torture_base_key = TEST_KEY_BASE;
3260 174 : } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3261 87 : hkey = HKEY_CLASSES_ROOT;
3262 87 : torture_base_key = TEST_KEY_BASE;
3263 87 : } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3264 87 : hkey = HKEY_CURRENT_USER;
3265 87 : torture_base_key = TEST_KEY_BASE;
3266 : } else {
3267 0 : torture_fail(tctx, "unsupported hkey");
3268 : }
3269 :
3270 348 : if (hkey == HKEY_LOCAL_MACHINE) {
3271 87 : torture_assert(tctx,
3272 : test_HKLM_wellknown(tctx, b, &handle),
3273 : "failed to test HKLM wellknown keys");
3274 : }
3275 :
3276 348 : if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3277 0 : torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3278 : torture_base_key);
3279 0 : ret = false;
3280 : }
3281 :
3282 348 : if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3283 0 : torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3284 : torture_base_key);
3285 0 : ret = false;
3286 : }
3287 :
3288 : /* The HKCR hive has a very large fanout */
3289 348 : if (hkey == HKEY_CLASSES_ROOT) {
3290 87 : if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3291 0 : ret = false;
3292 : }
3293 261 : } else if (hkey == HKEY_LOCAL_MACHINE) {
3294 : /* FIXME we are not allowed to enum values in the HKLM root */
3295 : } else {
3296 174 : if (!test_key(p, tctx, &handle, 0, false)) {
3297 0 : ret = false;
3298 : }
3299 : }
3300 :
3301 348 : return ret;
3302 : }
3303 :
3304 2354 : struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3305 : {
3306 125 : struct torture_rpc_tcase *tcase;
3307 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "winreg");
3308 125 : struct torture_test *test;
3309 :
3310 2354 : tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3311 : &ndr_table_winreg);
3312 :
3313 2354 : test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3314 : test_InitiateSystemShutdown);
3315 2354 : test->dangerous = true;
3316 :
3317 2354 : test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3318 : test_InitiateSystemShutdownEx);
3319 2354 : test->dangerous = true;
3320 :
3321 2354 : torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3322 : test_Open,
3323 : (void *)dcerpc_winreg_OpenHKLM_r);
3324 2354 : torture_rpc_tcase_add_test_ex(tcase, "HKU",
3325 : test_Open,
3326 : (void *)dcerpc_winreg_OpenHKU_r);
3327 2354 : torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3328 : test_Open,
3329 : (void *)dcerpc_winreg_OpenHKCR_r);
3330 2354 : torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3331 : test_Open,
3332 : (void *)dcerpc_winreg_OpenHKCU_r);
3333 :
3334 2354 : return suite;
3335 : }
|