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 41static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s) 42{ 43 name->string = s; 44} 45 46static void init_winreg_String(struct winreg_String *name, const char *s) 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 58static bool test_GetVersion(struct dcerpc_pipe *p, 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 77static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p, 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 105static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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*/ 135static bool test_CreateKey_sd(struct dcerpc_pipe *p, 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 186static bool _test_GetKeySecurity(struct dcerpc_pipe *p, 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 241static bool test_GetKeySecurity(struct dcerpc_pipe *p, 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 249static bool _test_SetKeySecurity(struct dcerpc_pipe *p, 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 310static bool test_SetKeySecurity(struct dcerpc_pipe *p, 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 318static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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 334static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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 350static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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 379static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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 388static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx, 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 402static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p, 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 421static bool test_SecurityDescriptor(struct dcerpc_pipe *p, 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 447static bool _test_SecurityDescriptor(struct dcerpc_pipe *p, 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 481static bool test_dacl_trustee_present(struct dcerpc_pipe *p, 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 506static bool _test_dacl_trustee_present(struct dcerpc_pipe *p, 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 526static bool test_sacl_trustee_present(struct dcerpc_pipe *p, 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 552static bool _test_sacl_trustee_present(struct dcerpc_pipe *p, 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 573static bool test_owner_present(struct dcerpc_pipe *p, 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 592static bool _test_owner_present(struct dcerpc_pipe *p, 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 612static bool test_group_present(struct dcerpc_pipe *p, 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 631static bool _test_group_present(struct dcerpc_pipe *p, 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 651static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p, 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 678static bool test_dacl_ace_present(struct dcerpc_pipe *p, 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 703static bool test_RestoreSecurity(struct dcerpc_pipe *p, 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 727static bool test_BackupSecurity(struct dcerpc_pipe *p, 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 751static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p, 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 864static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p, 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 986static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p, 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 1040typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *, 1041 struct torture_context *, 1042 struct policy_handle *, 1043 const char *, 1044 const struct dom_sid *); 1045 1046static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p, 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 1117static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p, 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 1342static bool test_SecurityDescriptors(struct dcerpc_pipe *p, 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 1377static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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 1394static bool test_QueryInfoKey(struct dcerpc_pipe *p, 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 1429static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx, 1430 struct policy_handle *handle, int depth, 1431 bool test_security); 1432 1433static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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 1488static bool test_QueryMultipleValues(struct dcerpc_pipe *p, 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 1528static bool test_QueryValue(struct dcerpc_pipe *p, 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 1558static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx, 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 1603static bool test_AbortSystemShutdown(struct dcerpc_pipe *p, 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 1622static bool test_InitiateSystemShutdown(struct torture_context *tctx, 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 1647static bool test_InitiateSystemShutdownEx(struct torture_context *tctx, 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 1673static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx, 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 1700typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *); 1701 1702static bool test_Open_Security(struct torture_context *tctx, 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 1776static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, 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 1879struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx) 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} 1926