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