1/* 2 Unix SMB/CIFS implementation. 3 test suite for lsa rpc operations 4 5 Copyright (C) Andrew Tridgell 2003 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "torture/torture.h" 24#include "librpc/gen_ndr/ndr_lsa_c.h" 25#include "librpc/gen_ndr/netlogon.h" 26#include "librpc/gen_ndr/ndr_drsblobs.h" 27#include "lib/events/events.h" 28#include "libcli/security/security.h" 29#include "libcli/auth/libcli_auth.h" 30#include "torture/rpc/rpc.h" 31#include "param/param.h" 32#include "../lib/crypto/crypto.h" 33#define TEST_MACHINENAME "lsatestmach" 34 35static void init_lsa_String(struct lsa_String *name, const char *s) 36{ 37 name->string = s; 38} 39 40static bool test_OpenPolicy(struct dcerpc_pipe *p, 41 struct torture_context *tctx) 42{ 43 struct lsa_ObjectAttribute attr; 44 struct policy_handle handle; 45 struct lsa_QosInfo qos; 46 struct lsa_OpenPolicy r; 47 NTSTATUS status; 48 uint16_t system_name = '\\'; 49 50 torture_comment(tctx, "\nTesting OpenPolicy\n"); 51 52 qos.len = 0; 53 qos.impersonation_level = 2; 54 qos.context_mode = 1; 55 qos.effective_only = 0; 56 57 attr.len = 0; 58 attr.root_dir = NULL; 59 attr.object_name = NULL; 60 attr.attributes = 0; 61 attr.sec_desc = NULL; 62 attr.sec_qos = &qos; 63 64 r.in.system_name = &system_name; 65 r.in.attr = &attr; 66 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 67 r.out.handle = &handle; 68 69 status = dcerpc_lsa_OpenPolicy(p, tctx, &r); 70 if (!NT_STATUS_IS_OK(status)) { 71 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || 72 NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { 73 torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); 74 return true; 75 } 76 torture_comment(tctx, "OpenPolicy failed - %s\n", nt_errstr(status)); 77 return false; 78 } 79 80 return true; 81} 82 83 84bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p, 85 struct torture_context *tctx, 86 struct policy_handle **handle) 87{ 88 struct lsa_ObjectAttribute attr; 89 struct lsa_QosInfo qos; 90 struct lsa_OpenPolicy2 r; 91 NTSTATUS status; 92 93 torture_comment(tctx, "\nTesting OpenPolicy2\n"); 94 95 *handle = talloc(tctx, struct policy_handle); 96 if (!*handle) { 97 return false; 98 } 99 100 qos.len = 0; 101 qos.impersonation_level = 2; 102 qos.context_mode = 1; 103 qos.effective_only = 0; 104 105 attr.len = 0; 106 attr.root_dir = NULL; 107 attr.object_name = NULL; 108 attr.attributes = 0; 109 attr.sec_desc = NULL; 110 attr.sec_qos = &qos; 111 112 r.in.system_name = "\\"; 113 r.in.attr = &attr; 114 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 115 r.out.handle = *handle; 116 117 status = dcerpc_lsa_OpenPolicy2(p, tctx, &r); 118 if (!NT_STATUS_IS_OK(status)) { 119 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || 120 NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { 121 torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); 122 talloc_free(*handle); 123 *handle = NULL; 124 return true; 125 } 126 torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status)); 127 return false; 128 } 129 130 return true; 131} 132 133 134static const char *sid_type_lookup(enum lsa_SidType r) 135{ 136 switch (r) { 137 case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break; 138 case SID_NAME_USER: return "SID_NAME_USER"; break; 139 case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break; 140 case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break; 141 case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break; 142 case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break; 143 case SID_NAME_DELETED: return "SID_NAME_DELETED"; break; 144 case SID_NAME_INVALID: return "SID_NAME_INVALID"; break; 145 case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break; 146 case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break; 147 } 148 return "Invalid sid type\n"; 149} 150 151static bool test_LookupNames(struct dcerpc_pipe *p, 152 struct torture_context *tctx, 153 struct policy_handle *handle, 154 struct lsa_TransNameArray *tnames) 155{ 156 struct lsa_LookupNames r; 157 struct lsa_TransSidArray sids; 158 struct lsa_RefDomainList *domains = NULL; 159 struct lsa_String *names; 160 uint32_t count = 0; 161 NTSTATUS status; 162 int i; 163 164 torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count); 165 166 sids.count = 0; 167 sids.sids = NULL; 168 169 names = talloc_array(tctx, struct lsa_String, tnames->count); 170 for (i=0;i<tnames->count;i++) { 171 init_lsa_String(&names[i], tnames->names[i].name.string); 172 } 173 174 r.in.handle = handle; 175 r.in.num_names = tnames->count; 176 r.in.names = names; 177 r.in.sids = &sids; 178 r.in.level = 1; 179 r.in.count = &count; 180 r.out.count = &count; 181 r.out.sids = &sids; 182 r.out.domains = &domains; 183 184 status = dcerpc_lsa_LookupNames(p, tctx, &r); 185 186 if (NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED) || 187 NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { 188 for (i=0;i< tnames->count;i++) { 189 if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) { 190 torture_comment(tctx, "LookupName of %s was unmapped\n", 191 tnames->names[i].name.string); 192 } else if (i >=count) { 193 torture_comment(tctx, "LookupName of %s failed to return a result\n", 194 tnames->names[i].name.string); 195 } 196 } 197 torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status)); 198 return false; 199 } else if (!NT_STATUS_IS_OK(status)) { 200 torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status)); 201 return false; 202 } 203 204 for (i=0;i< tnames->count;i++) { 205 if (i < count) { 206 if (sids.sids[i].sid_type != tnames->names[i].sid_type) { 207 torture_comment(tctx, "LookupName of %s got unexpected name type: %s\n", 208 tnames->names[i].name.string, sid_type_lookup(sids.sids[i].sid_type)); 209 return false; 210 } 211 if ((sids.sids[i].sid_type == SID_NAME_DOMAIN) && 212 (sids.sids[i].rid != (uint32_t)-1)) { 213 torture_comment(tctx, "LookupName of %s got unexpected rid: %d\n", 214 tnames->names[i].name.string, sids.sids[i].rid); 215 return false; 216 } 217 } else if (i >=count) { 218 torture_comment(tctx, "LookupName of %s failed to return a result\n", 219 tnames->names[i].name.string); 220 return false; 221 } 222 } 223 torture_comment(tctx, "\n"); 224 225 return true; 226} 227 228static bool test_LookupNames_bogus(struct dcerpc_pipe *p, 229 struct torture_context *tctx, 230 struct policy_handle *handle) 231{ 232 struct lsa_LookupNames r; 233 struct lsa_TransSidArray sids; 234 struct lsa_RefDomainList *domains = NULL; 235 struct lsa_String names[1]; 236 uint32_t count = 0; 237 NTSTATUS status; 238 239 torture_comment(tctx, "\nTesting LookupNames with bogus name\n"); 240 241 sids.count = 0; 242 sids.sids = NULL; 243 244 init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS"); 245 246 r.in.handle = handle; 247 r.in.num_names = 1; 248 r.in.names = names; 249 r.in.sids = &sids; 250 r.in.level = 1; 251 r.in.count = &count; 252 r.out.count = &count; 253 r.out.sids = &sids; 254 r.out.domains = &domains; 255 256 status = dcerpc_lsa_LookupNames(p, tctx, &r); 257 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { 258 torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status)); 259 return false; 260 } 261 262 torture_comment(tctx, "\n"); 263 264 return true; 265} 266 267static bool test_LookupNames_NULL(struct dcerpc_pipe *p, 268 struct torture_context *tctx, 269 struct policy_handle *handle) 270{ 271 struct lsa_LookupNames r; 272 struct lsa_TransSidArray sids; 273 struct lsa_RefDomainList *domains = NULL; 274 struct lsa_String names[1]; 275 uint32_t count = 0; 276 277 torture_comment(tctx, "\nTesting LookupNames with NULL name\n"); 278 279 sids.count = 0; 280 sids.sids = NULL; 281 282 names[0].string = NULL; 283 284 r.in.handle = handle; 285 r.in.num_names = 1; 286 r.in.names = names; 287 r.in.sids = &sids; 288 r.in.level = 1; 289 r.in.count = &count; 290 r.out.count = &count; 291 r.out.sids = &sids; 292 r.out.domains = &domains; 293 294 /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type 295 * SID_NAME_UNKNOWN, rid 0, and sid_index -1; 296 * 297 * w2k3/w2k8 return NT_STATUS_OK with sid_type 298 * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain 299 */ 300 301 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames(p, tctx, &r), 302 "LookupNames with NULL name failed"); 303 304 torture_comment(tctx, "\n"); 305 306 return true; 307} 308 309static bool test_LookupNames_wellknown(struct dcerpc_pipe *p, 310 struct torture_context *tctx, 311 struct policy_handle *handle) 312{ 313 struct lsa_TranslatedName name; 314 struct lsa_TransNameArray tnames; 315 bool ret = true; 316 317 torture_comment(tctx, "Testing LookupNames with well known names\n"); 318 319 tnames.names = &name; 320 tnames.count = 1; 321 name.name.string = "NT AUTHORITY\\SYSTEM"; 322 name.sid_type = SID_NAME_WKN_GRP; 323 ret &= test_LookupNames(p, tctx, handle, &tnames); 324 325 name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON"; 326 name.sid_type = SID_NAME_WKN_GRP; 327 ret &= test_LookupNames(p, tctx, handle, &tnames); 328 329 name.name.string = "NT AUTHORITY\\Authenticated Users"; 330 name.sid_type = SID_NAME_WKN_GRP; 331 ret &= test_LookupNames(p, tctx, handle, &tnames); 332 333#if 0 334 name.name.string = "NT AUTHORITY"; 335 ret &= test_LookupNames(p, tctx, handle, &tnames); 336 337 name.name.string = "NT AUTHORITY\\"; 338 ret &= test_LookupNames(p, tctx, handle, &tnames); 339#endif 340 341 name.name.string = "BUILTIN\\"; 342 name.sid_type = SID_NAME_DOMAIN; 343 ret &= test_LookupNames(p, tctx, handle, &tnames); 344 345 name.name.string = "BUILTIN\\Administrators"; 346 name.sid_type = SID_NAME_ALIAS; 347 ret &= test_LookupNames(p, tctx, handle, &tnames); 348 349 name.name.string = "SYSTEM"; 350 name.sid_type = SID_NAME_WKN_GRP; 351 ret &= test_LookupNames(p, tctx, handle, &tnames); 352 353 name.name.string = "Everyone"; 354 name.sid_type = SID_NAME_WKN_GRP; 355 ret &= test_LookupNames(p, tctx, handle, &tnames); 356 return ret; 357} 358 359static bool test_LookupNames2(struct dcerpc_pipe *p, 360 struct torture_context *tctx, 361 struct policy_handle *handle, 362 struct lsa_TransNameArray2 *tnames, 363 bool check_result) 364{ 365 struct lsa_LookupNames2 r; 366 struct lsa_TransSidArray2 sids; 367 struct lsa_RefDomainList *domains = NULL; 368 struct lsa_String *names; 369 uint32_t count = 0; 370 NTSTATUS status; 371 int i; 372 373 torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count); 374 375 sids.count = 0; 376 sids.sids = NULL; 377 378 names = talloc_array(tctx, struct lsa_String, tnames->count); 379 for (i=0;i<tnames->count;i++) { 380 init_lsa_String(&names[i], tnames->names[i].name.string); 381 } 382 383 r.in.handle = handle; 384 r.in.num_names = tnames->count; 385 r.in.names = names; 386 r.in.sids = &sids; 387 r.in.level = 1; 388 r.in.count = &count; 389 r.in.lookup_options = 0; 390 r.in.client_revision = 0; 391 r.out.count = &count; 392 r.out.sids = &sids; 393 r.out.domains = &domains; 394 395 status = dcerpc_lsa_LookupNames2(p, tctx, &r); 396 if (!NT_STATUS_IS_OK(status)) { 397 torture_comment(tctx, "LookupNames2 failed - %s\n", nt_errstr(status)); 398 return false; 399 } 400 401 if (check_result) { 402 torture_assert_int_equal(tctx, count, sids.count, 403 "unexpected number of results returned"); 404 if (sids.count > 0) { 405 torture_assert(tctx, sids.sids, "invalid sid buffer"); 406 } 407 } 408 409 torture_comment(tctx, "\n"); 410 411 return true; 412} 413 414 415static bool test_LookupNames3(struct dcerpc_pipe *p, 416 struct torture_context *tctx, 417 struct policy_handle *handle, 418 struct lsa_TransNameArray2 *tnames, 419 bool check_result) 420{ 421 struct lsa_LookupNames3 r; 422 struct lsa_TransSidArray3 sids; 423 struct lsa_RefDomainList *domains = NULL; 424 struct lsa_String *names; 425 uint32_t count = 0; 426 NTSTATUS status; 427 int i; 428 429 torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count); 430 431 sids.count = 0; 432 sids.sids = NULL; 433 434 names = talloc_array(tctx, struct lsa_String, tnames->count); 435 for (i=0;i<tnames->count;i++) { 436 init_lsa_String(&names[i], tnames->names[i].name.string); 437 } 438 439 r.in.handle = handle; 440 r.in.num_names = tnames->count; 441 r.in.names = names; 442 r.in.sids = &sids; 443 r.in.level = 1; 444 r.in.count = &count; 445 r.in.lookup_options = 0; 446 r.in.client_revision = 0; 447 r.out.count = &count; 448 r.out.sids = &sids; 449 r.out.domains = &domains; 450 451 status = dcerpc_lsa_LookupNames3(p, tctx, &r); 452 if (!NT_STATUS_IS_OK(status)) { 453 torture_comment(tctx, "LookupNames3 failed - %s\n", nt_errstr(status)); 454 return false; 455 } 456 457 if (check_result) { 458 torture_assert_int_equal(tctx, count, sids.count, 459 "unexpected number of results returned"); 460 if (sids.count > 0) { 461 torture_assert(tctx, sids.sids, "invalid sid buffer"); 462 } 463 } 464 465 torture_comment(tctx, "\n"); 466 467 return true; 468} 469 470static bool test_LookupNames4(struct dcerpc_pipe *p, 471 struct torture_context *tctx, 472 struct lsa_TransNameArray2 *tnames, 473 bool check_result) 474{ 475 struct lsa_LookupNames4 r; 476 struct lsa_TransSidArray3 sids; 477 struct lsa_RefDomainList *domains = NULL; 478 struct lsa_String *names; 479 uint32_t count = 0; 480 NTSTATUS status; 481 int i; 482 483 torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count); 484 485 sids.count = 0; 486 sids.sids = NULL; 487 488 names = talloc_array(tctx, struct lsa_String, tnames->count); 489 for (i=0;i<tnames->count;i++) { 490 init_lsa_String(&names[i], tnames->names[i].name.string); 491 } 492 493 r.in.num_names = tnames->count; 494 r.in.names = names; 495 r.in.sids = &sids; 496 r.in.level = 1; 497 r.in.count = &count; 498 r.in.lookup_options = 0; 499 r.in.client_revision = 0; 500 r.out.count = &count; 501 r.out.sids = &sids; 502 r.out.domains = &domains; 503 504 status = dcerpc_lsa_LookupNames4(p, tctx, &r); 505 if (!NT_STATUS_IS_OK(status)) { 506 torture_comment(tctx, "LookupNames4 failed - %s\n", nt_errstr(status)); 507 return false; 508 } 509 510 if (check_result) { 511 torture_assert_int_equal(tctx, count, sids.count, 512 "unexpected number of results returned"); 513 if (sids.count > 0) { 514 torture_assert(tctx, sids.sids, "invalid sid buffer"); 515 } 516 } 517 518 torture_comment(tctx, "\n"); 519 520 return true; 521} 522 523 524static bool test_LookupSids(struct dcerpc_pipe *p, 525 struct torture_context *tctx, 526 struct policy_handle *handle, 527 struct lsa_SidArray *sids) 528{ 529 struct lsa_LookupSids r; 530 struct lsa_TransNameArray names; 531 struct lsa_RefDomainList *domains = NULL; 532 uint32_t count = sids->num_sids; 533 NTSTATUS status; 534 535 torture_comment(tctx, "\nTesting LookupSids\n"); 536 537 names.count = 0; 538 names.names = NULL; 539 540 r.in.handle = handle; 541 r.in.sids = sids; 542 r.in.names = &names; 543 r.in.level = 1; 544 r.in.count = &count; 545 r.out.count = &count; 546 r.out.names = &names; 547 r.out.domains = &domains; 548 549 status = dcerpc_lsa_LookupSids(p, tctx, &r); 550 if (!NT_STATUS_IS_OK(status)) { 551 torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status)); 552 return false; 553 } 554 555 torture_comment(tctx, "\n"); 556 557 if (!test_LookupNames(p, tctx, handle, &names)) { 558 return false; 559 } 560 561 return true; 562} 563 564 565static bool test_LookupSids2(struct dcerpc_pipe *p, 566 struct torture_context *tctx, 567 struct policy_handle *handle, 568 struct lsa_SidArray *sids) 569{ 570 struct lsa_LookupSids2 r; 571 struct lsa_TransNameArray2 names; 572 struct lsa_RefDomainList *domains = NULL; 573 uint32_t count = sids->num_sids; 574 NTSTATUS status; 575 576 torture_comment(tctx, "\nTesting LookupSids2\n"); 577 578 names.count = 0; 579 names.names = NULL; 580 581 r.in.handle = handle; 582 r.in.sids = sids; 583 r.in.names = &names; 584 r.in.level = 1; 585 r.in.count = &count; 586 r.in.lookup_options = 0; 587 r.in.client_revision = 0; 588 r.out.count = &count; 589 r.out.names = &names; 590 r.out.domains = &domains; 591 592 status = dcerpc_lsa_LookupSids2(p, tctx, &r); 593 if (!NT_STATUS_IS_OK(status)) { 594 torture_comment(tctx, "LookupSids2 failed - %s\n", nt_errstr(status)); 595 return false; 596 } 597 598 torture_comment(tctx, "\n"); 599 600 if (!test_LookupNames2(p, tctx, handle, &names, false)) { 601 return false; 602 } 603 604 if (!test_LookupNames3(p, tctx, handle, &names, false)) { 605 return false; 606 } 607 608 return true; 609} 610 611static bool test_LookupSids3(struct dcerpc_pipe *p, 612 struct torture_context *tctx, 613 struct lsa_SidArray *sids) 614{ 615 struct lsa_LookupSids3 r; 616 struct lsa_TransNameArray2 names; 617 struct lsa_RefDomainList *domains = NULL; 618 uint32_t count = sids->num_sids; 619 NTSTATUS status; 620 621 torture_comment(tctx, "\nTesting LookupSids3\n"); 622 623 names.count = 0; 624 names.names = NULL; 625 626 r.in.sids = sids; 627 r.in.names = &names; 628 r.in.level = 1; 629 r.in.count = &count; 630 r.in.lookup_options = 0; 631 r.in.client_revision = 0; 632 r.out.domains = &domains; 633 r.out.count = &count; 634 r.out.names = &names; 635 636 status = dcerpc_lsa_LookupSids3(p, tctx, &r); 637 if (!NT_STATUS_IS_OK(status)) { 638 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || 639 NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { 640 torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); 641 return true; 642 } 643 torture_comment(tctx, "LookupSids3 failed - %s - not considered an error\n", 644 nt_errstr(status)); 645 return false; 646 } 647 648 torture_comment(tctx, "\n"); 649 650 if (!test_LookupNames4(p, tctx, &names, false)) { 651 return false; 652 } 653 654 return true; 655} 656 657bool test_many_LookupSids(struct dcerpc_pipe *p, 658 struct torture_context *tctx, 659 struct policy_handle *handle) 660{ 661 uint32_t count; 662 NTSTATUS status; 663 struct lsa_SidArray sids; 664 int i; 665 666 torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n"); 667 668 sids.num_sids = 100; 669 670 sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids); 671 672 for (i=0; i<sids.num_sids; i++) { 673 const char *sidstr = "S-1-5-32-545"; 674 sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr); 675 } 676 677 count = sids.num_sids; 678 679 if (handle) { 680 struct lsa_LookupSids r; 681 struct lsa_TransNameArray names; 682 struct lsa_RefDomainList *domains = NULL; 683 names.count = 0; 684 names.names = NULL; 685 686 r.in.handle = handle; 687 r.in.sids = &sids; 688 r.in.names = &names; 689 r.in.level = 1; 690 r.in.count = &names.count; 691 r.out.count = &count; 692 r.out.names = &names; 693 r.out.domains = &domains; 694 695 status = dcerpc_lsa_LookupSids(p, tctx, &r); 696 if (!NT_STATUS_IS_OK(status)) { 697 torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status)); 698 return false; 699 } 700 701 torture_comment(tctx, "\n"); 702 703 if (!test_LookupNames(p, tctx, handle, &names)) { 704 return false; 705 } 706 } else if (p->conn->security_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL && 707 p->conn->security_state.auth_info->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { 708 struct lsa_LookupSids3 r; 709 struct lsa_RefDomainList *domains = NULL; 710 struct lsa_TransNameArray2 names; 711 712 names.count = 0; 713 names.names = NULL; 714 715 torture_comment(tctx, "\nTesting LookupSids3\n"); 716 717 r.in.sids = &sids; 718 r.in.names = &names; 719 r.in.level = 1; 720 r.in.count = &count; 721 r.in.lookup_options = 0; 722 r.in.client_revision = 0; 723 r.out.count = &count; 724 r.out.names = &names; 725 r.out.domains = &domains; 726 727 status = dcerpc_lsa_LookupSids3(p, tctx, &r); 728 if (!NT_STATUS_IS_OK(status)) { 729 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || 730 NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) { 731 torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status)); 732 return true; 733 } 734 torture_comment(tctx, "LookupSids3 failed - %s\n", 735 nt_errstr(status)); 736 return false; 737 } 738 if (!test_LookupNames4(p, tctx, &names, false)) { 739 return false; 740 } 741 } 742 743 torture_comment(tctx, "\n"); 744 745 746 747 return true; 748} 749 750static void lookupsids_cb(struct rpc_request *req) 751{ 752 int *replies = (int *)req->async.private_data; 753 NTSTATUS status; 754 755 status = dcerpc_ndr_request_recv(req); 756 if (!NT_STATUS_IS_OK(status)) { 757 printf("lookupsids returned %s\n", nt_errstr(status)); 758 *replies = -1; 759 } 760 761 if (*replies >= 0) { 762 *replies += 1; 763 } 764} 765 766static bool test_LookupSids_async(struct dcerpc_pipe *p, 767 struct torture_context *tctx, 768 struct policy_handle *handle) 769{ 770 struct lsa_SidArray sids; 771 struct lsa_SidPtr sidptr; 772 uint32_t *count; 773 struct lsa_TransNameArray *names; 774 struct lsa_LookupSids *r; 775 struct lsa_RefDomainList *domains = NULL; 776 struct rpc_request **req; 777 int i, replies; 778 bool ret = true; 779 const int num_async_requests = 50; 780 781 count = talloc_array(tctx, uint32_t, num_async_requests); 782 names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests); 783 r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests); 784 785 torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests); 786 787 req = talloc_array(tctx, struct rpc_request *, num_async_requests); 788 789 sids.num_sids = 1; 790 sids.sids = &sidptr; 791 sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545"); 792 793 replies = 0; 794 795 for (i=0; i<num_async_requests; i++) { 796 count[i] = 0; 797 names[i].count = 0; 798 names[i].names = NULL; 799 800 r[i].in.handle = handle; 801 r[i].in.sids = &sids; 802 r[i].in.names = &names[i]; 803 r[i].in.level = 1; 804 r[i].in.count = &names[i].count; 805 r[i].out.count = &count[i]; 806 r[i].out.names = &names[i]; 807 r[i].out.domains = &domains; 808 809 req[i] = dcerpc_lsa_LookupSids_send(p, req, &r[i]); 810 if (req[i] == NULL) { 811 ret = false; 812 break; 813 } 814 815 req[i]->async.callback = lookupsids_cb; 816 req[i]->async.private_data = &replies; 817 } 818 819 while (replies >= 0 && replies < num_async_requests) { 820 event_loop_once(p->conn->event_ctx); 821 } 822 823 talloc_free(req); 824 825 if (replies < 0) { 826 ret = false; 827 } 828 829 return ret; 830} 831 832static bool test_LookupPrivValue(struct dcerpc_pipe *p, 833 struct torture_context *tctx, 834 struct policy_handle *handle, 835 struct lsa_String *name) 836{ 837 NTSTATUS status; 838 struct lsa_LookupPrivValue r; 839 struct lsa_LUID luid; 840 841 r.in.handle = handle; 842 r.in.name = name; 843 r.out.luid = &luid; 844 845 status = dcerpc_lsa_LookupPrivValue(p, tctx, &r); 846 if (!NT_STATUS_IS_OK(status)) { 847 torture_comment(tctx, "\nLookupPrivValue failed - %s\n", nt_errstr(status)); 848 return false; 849 } 850 851 return true; 852} 853 854static bool test_LookupPrivName(struct dcerpc_pipe *p, 855 struct torture_context *tctx, 856 struct policy_handle *handle, 857 struct lsa_LUID *luid) 858{ 859 NTSTATUS status; 860 struct lsa_LookupPrivName r; 861 struct lsa_StringLarge *name = NULL; 862 863 r.in.handle = handle; 864 r.in.luid = luid; 865 r.out.name = &name; 866 867 status = dcerpc_lsa_LookupPrivName(p, tctx, &r); 868 if (!NT_STATUS_IS_OK(status)) { 869 torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status)); 870 return false; 871 } 872 873 return true; 874} 875 876static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, 877 struct torture_context *tctx, 878 struct policy_handle *handle, 879 struct policy_handle *acct_handle, 880 struct lsa_LUID *luid) 881{ 882 NTSTATUS status; 883 struct lsa_RemovePrivilegesFromAccount r; 884 struct lsa_PrivilegeSet privs; 885 bool ret = true; 886 887 torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n"); 888 889 r.in.handle = acct_handle; 890 r.in.remove_all = 0; 891 r.in.privs = &privs; 892 893 privs.count = 1; 894 privs.unknown = 0; 895 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1); 896 privs.set[0].luid = *luid; 897 privs.set[0].attribute = 0; 898 899 status = dcerpc_lsa_RemovePrivilegesFromAccount(p, tctx, &r); 900 if (!NT_STATUS_IS_OK(status)) { 901 902 struct lsa_LookupPrivName r_name; 903 struct lsa_StringLarge *name = NULL; 904 905 r_name.in.handle = handle; 906 r_name.in.luid = luid; 907 r_name.out.name = &name; 908 909 status = dcerpc_lsa_LookupPrivName(p, tctx, &r_name); 910 if (!NT_STATUS_IS_OK(status)) { 911 torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status)); 912 return false; 913 } 914 /* Windows 2008 does not allow this to be removed */ 915 if (strcmp("SeAuditPrivilege", name->string) == 0) { 916 return ret; 917 } 918 919 torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n", 920 name->string, 921 nt_errstr(status)); 922 return false; 923 } 924 925 return ret; 926} 927 928static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p, 929 struct torture_context *tctx, 930 struct policy_handle *acct_handle, 931 struct lsa_LUID *luid) 932{ 933 NTSTATUS status; 934 struct lsa_AddPrivilegesToAccount r; 935 struct lsa_PrivilegeSet privs; 936 bool ret = true; 937 938 torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n"); 939 940 r.in.handle = acct_handle; 941 r.in.privs = &privs; 942 943 privs.count = 1; 944 privs.unknown = 0; 945 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1); 946 privs.set[0].luid = *luid; 947 privs.set[0].attribute = 0; 948 949 status = dcerpc_lsa_AddPrivilegesToAccount(p, tctx, &r); 950 if (!NT_STATUS_IS_OK(status)) { 951 torture_comment(tctx, "AddPrivilegesToAccount failed - %s\n", nt_errstr(status)); 952 return false; 953 } 954 955 return ret; 956} 957 958static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, 959 struct torture_context *tctx, 960 struct policy_handle *handle, 961 struct policy_handle *acct_handle) 962{ 963 NTSTATUS status; 964 struct lsa_EnumPrivsAccount r; 965 struct lsa_PrivilegeSet *privs = NULL; 966 bool ret = true; 967 968 torture_comment(tctx, "\nTesting EnumPrivsAccount\n"); 969 970 r.in.handle = acct_handle; 971 r.out.privs = &privs; 972 973 status = dcerpc_lsa_EnumPrivsAccount(p, tctx, &r); 974 if (!NT_STATUS_IS_OK(status)) { 975 torture_comment(tctx, "EnumPrivsAccount failed - %s\n", nt_errstr(status)); 976 return false; 977 } 978 979 if (privs && privs->count > 0) { 980 int i; 981 for (i=0;i<privs->count;i++) { 982 test_LookupPrivName(p, tctx, handle, 983 &privs->set[i].luid); 984 } 985 986 ret &= test_RemovePrivilegesFromAccount(p, tctx, handle, acct_handle, 987 &privs->set[0].luid); 988 ret &= test_AddPrivilegesToAccount(p, tctx, acct_handle, 989 &privs->set[0].luid); 990 } 991 992 return ret; 993} 994 995static bool test_GetSystemAccessAccount(struct dcerpc_pipe *p, 996 struct torture_context *tctx, 997 struct policy_handle *handle, 998 struct policy_handle *acct_handle) 999{ 1000 NTSTATUS status; 1001 uint32_t access_mask; 1002 struct lsa_GetSystemAccessAccount r; 1003 1004 torture_comment(tctx, "\nTesting GetSystemAccessAccount\n"); 1005 1006 r.in.handle = acct_handle; 1007 r.out.access_mask = &access_mask; 1008 1009 status = dcerpc_lsa_GetSystemAccessAccount(p, tctx, &r); 1010 if (!NT_STATUS_IS_OK(status)) { 1011 torture_comment(tctx, "GetSystemAccessAccount failed - %s\n", nt_errstr(status)); 1012 return false; 1013 } 1014 1015 if (r.out.access_mask != NULL) { 1016 torture_comment(tctx, "Rights:"); 1017 if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE) 1018 torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE"); 1019 if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK) 1020 torture_comment(tctx, " LSA_POLICY_MODE_NETWORK"); 1021 if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH) 1022 torture_comment(tctx, " LSA_POLICY_MODE_BATCH"); 1023 if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE) 1024 torture_comment(tctx, " LSA_POLICY_MODE_SERVICE"); 1025 if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY) 1026 torture_comment(tctx, " LSA_POLICY_MODE_PROXY"); 1027 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE) 1028 torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE"); 1029 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK) 1030 torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK"); 1031 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH) 1032 torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH"); 1033 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE) 1034 torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE"); 1035 if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE) 1036 torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE"); 1037 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE) 1038 torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE"); 1039 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL) 1040 torture_comment(tctx, " LSA_POLICY_MODE_ALL"); 1041 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4) 1042 torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4"); 1043 torture_comment(tctx, "\n"); 1044 } 1045 1046 return true; 1047} 1048 1049static bool test_Delete(struct dcerpc_pipe *p, 1050 struct torture_context *tctx, 1051 struct policy_handle *handle) 1052{ 1053 NTSTATUS status; 1054 struct lsa_Delete r; 1055 1056 torture_comment(tctx, "\nTesting Delete\n"); 1057 1058 r.in.handle = handle; 1059 status = dcerpc_lsa_Delete(p, tctx, &r); 1060 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { 1061 torture_comment(tctx, "Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status)); 1062 return false; 1063 } 1064 1065 return true; 1066} 1067 1068static bool test_DeleteObject(struct dcerpc_pipe *p, 1069 struct torture_context *tctx, 1070 struct policy_handle *handle) 1071{ 1072 NTSTATUS status; 1073 struct lsa_DeleteObject r; 1074 1075 torture_comment(tctx, "\nTesting DeleteObject\n"); 1076 1077 r.in.handle = handle; 1078 r.out.handle = handle; 1079 status = dcerpc_lsa_DeleteObject(p, tctx, &r); 1080 if (!NT_STATUS_IS_OK(status)) { 1081 torture_comment(tctx, "DeleteObject failed - %s\n", nt_errstr(status)); 1082 return false; 1083 } 1084 1085 return true; 1086} 1087 1088 1089static bool test_CreateAccount(struct dcerpc_pipe *p, 1090 struct torture_context *tctx, 1091 struct policy_handle *handle) 1092{ 1093 NTSTATUS status; 1094 struct lsa_CreateAccount r; 1095 struct dom_sid2 *newsid; 1096 struct policy_handle acct_handle; 1097 1098 newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854"); 1099 1100 torture_comment(tctx, "\nTesting CreateAccount\n"); 1101 1102 r.in.handle = handle; 1103 r.in.sid = newsid; 1104 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1105 r.out.acct_handle = &acct_handle; 1106 1107 status = dcerpc_lsa_CreateAccount(p, tctx, &r); 1108 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { 1109 struct lsa_OpenAccount r_o; 1110 r_o.in.handle = handle; 1111 r_o.in.sid = newsid; 1112 r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1113 r_o.out.acct_handle = &acct_handle; 1114 1115 status = dcerpc_lsa_OpenAccount(p, tctx, &r_o); 1116 if (!NT_STATUS_IS_OK(status)) { 1117 torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status)); 1118 return false; 1119 } 1120 } else if (!NT_STATUS_IS_OK(status)) { 1121 torture_comment(tctx, "CreateAccount failed - %s\n", nt_errstr(status)); 1122 return false; 1123 } 1124 1125 if (!test_Delete(p, tctx, &acct_handle)) { 1126 return false; 1127 } 1128 1129 if (!test_DeleteObject(p, tctx, &acct_handle)) { 1130 return false; 1131 } 1132 1133 return true; 1134} 1135 1136static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p, 1137 struct torture_context *tctx, 1138 struct policy_handle *handle, 1139 struct lsa_StringLarge name) 1140{ 1141 NTSTATUS status; 1142 struct lsa_OpenTrustedDomainByName r; 1143 struct policy_handle trustdom_handle; 1144 1145 r.in.handle = handle; 1146 r.in.name.string = name.string; 1147 r.in.access_mask = SEC_STD_DELETE; 1148 r.out.trustdom_handle = &trustdom_handle; 1149 1150 status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &r); 1151 if (!NT_STATUS_IS_OK(status)) { 1152 torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); 1153 return false; 1154 } 1155 1156 if (!test_Delete(p, tctx, &trustdom_handle)) { 1157 return false; 1158 } 1159 1160 if (!test_DeleteObject(p, tctx, &trustdom_handle)) { 1161 return false; 1162 } 1163 1164 return true; 1165} 1166 1167static bool test_DeleteTrustedDomainBySid(struct dcerpc_pipe *p, 1168 struct torture_context *tctx, 1169 struct policy_handle *handle, 1170 struct dom_sid *sid) 1171{ 1172 NTSTATUS status; 1173 struct lsa_DeleteTrustedDomain r; 1174 1175 r.in.handle = handle; 1176 r.in.dom_sid = sid; 1177 1178 status = dcerpc_lsa_DeleteTrustedDomain(p, tctx, &r); 1179 if (!NT_STATUS_IS_OK(status)) { 1180 torture_comment(tctx, "DeleteTrustedDomain failed - %s\n", nt_errstr(status)); 1181 return false; 1182 } 1183 1184 return true; 1185} 1186 1187 1188static bool test_CreateSecret(struct dcerpc_pipe *p, 1189 struct torture_context *tctx, 1190 struct policy_handle *handle) 1191{ 1192 NTSTATUS status; 1193 struct lsa_CreateSecret r; 1194 struct lsa_OpenSecret r2; 1195 struct lsa_SetSecret r3; 1196 struct lsa_QuerySecret r4; 1197 struct lsa_SetSecret r5; 1198 struct lsa_QuerySecret r6; 1199 struct lsa_SetSecret r7; 1200 struct lsa_QuerySecret r8; 1201 struct policy_handle sec_handle, sec_handle2, sec_handle3; 1202 struct lsa_DeleteObject d_o; 1203 struct lsa_DATA_BUF buf1; 1204 struct lsa_DATA_BUF_PTR bufp1; 1205 struct lsa_DATA_BUF_PTR bufp2; 1206 DATA_BLOB enc_key; 1207 bool ret = true; 1208 DATA_BLOB session_key; 1209 NTTIME old_mtime, new_mtime; 1210 DATA_BLOB blob1, blob2; 1211 const char *secret1 = "abcdef12345699qwerty"; 1212 char *secret2; 1213 const char *secret3 = "ABCDEF12345699QWERTY"; 1214 char *secret4; 1215 const char *secret5 = "NEW-SAMBA4-SECRET"; 1216 char *secret6; 1217 char *secname[2]; 1218 int i; 1219 const int LOCAL = 0; 1220 const int GLOBAL = 1; 1221 1222 secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (uint_t)random()); 1223 secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (uint_t)random()); 1224 1225 for (i=0; i< 2; i++) { 1226 torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]); 1227 1228 init_lsa_String(&r.in.name, secname[i]); 1229 1230 r.in.handle = handle; 1231 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1232 r.out.sec_handle = &sec_handle; 1233 1234 status = dcerpc_lsa_CreateSecret(p, tctx, &r); 1235 if (!NT_STATUS_IS_OK(status)) { 1236 torture_comment(tctx, "CreateSecret failed - %s\n", nt_errstr(status)); 1237 return false; 1238 } 1239 1240 r.in.handle = handle; 1241 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1242 r.out.sec_handle = &sec_handle3; 1243 1244 status = dcerpc_lsa_CreateSecret(p, tctx, &r); 1245 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { 1246 torture_comment(tctx, "CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status)); 1247 return false; 1248 } 1249 1250 r2.in.handle = handle; 1251 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1252 r2.in.name = r.in.name; 1253 r2.out.sec_handle = &sec_handle2; 1254 1255 torture_comment(tctx, "Testing OpenSecret\n"); 1256 1257 status = dcerpc_lsa_OpenSecret(p, tctx, &r2); 1258 if (!NT_STATUS_IS_OK(status)) { 1259 torture_comment(tctx, "OpenSecret failed - %s\n", nt_errstr(status)); 1260 return false; 1261 } 1262 1263 status = dcerpc_fetch_session_key(p, &session_key); 1264 if (!NT_STATUS_IS_OK(status)) { 1265 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); 1266 return false; 1267 } 1268 1269 enc_key = sess_encrypt_string(secret1, &session_key); 1270 1271 r3.in.sec_handle = &sec_handle; 1272 r3.in.new_val = &buf1; 1273 r3.in.old_val = NULL; 1274 r3.in.new_val->data = enc_key.data; 1275 r3.in.new_val->length = enc_key.length; 1276 r3.in.new_val->size = enc_key.length; 1277 1278 torture_comment(tctx, "Testing SetSecret\n"); 1279 1280 status = dcerpc_lsa_SetSecret(p, tctx, &r3); 1281 if (!NT_STATUS_IS_OK(status)) { 1282 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status)); 1283 return false; 1284 } 1285 1286 r3.in.sec_handle = &sec_handle; 1287 r3.in.new_val = &buf1; 1288 r3.in.old_val = NULL; 1289 r3.in.new_val->data = enc_key.data; 1290 r3.in.new_val->length = enc_key.length; 1291 r3.in.new_val->size = enc_key.length; 1292 1293 /* break the encrypted data */ 1294 enc_key.data[0]++; 1295 1296 torture_comment(tctx, "Testing SetSecret with broken key\n"); 1297 1298 status = dcerpc_lsa_SetSecret(p, tctx, &r3); 1299 if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) { 1300 torture_comment(tctx, "SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status)); 1301 ret = false; 1302 } 1303 1304 data_blob_free(&enc_key); 1305 1306 ZERO_STRUCT(new_mtime); 1307 ZERO_STRUCT(old_mtime); 1308 1309 /* fetch the secret back again */ 1310 r4.in.sec_handle = &sec_handle; 1311 r4.in.new_val = &bufp1; 1312 r4.in.new_mtime = &new_mtime; 1313 r4.in.old_val = NULL; 1314 r4.in.old_mtime = NULL; 1315 1316 bufp1.buf = NULL; 1317 1318 torture_comment(tctx, "Testing QuerySecret\n"); 1319 status = dcerpc_lsa_QuerySecret(p, tctx, &r4); 1320 if (!NT_STATUS_IS_OK(status)) { 1321 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status)); 1322 ret = false; 1323 } else { 1324 if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) { 1325 torture_comment(tctx, "No secret buffer returned\n"); 1326 ret = false; 1327 } else { 1328 blob1.data = r4.out.new_val->buf->data; 1329 blob1.length = r4.out.new_val->buf->size; 1330 1331 blob2 = data_blob_talloc(tctx, NULL, blob1.length); 1332 1333 secret2 = sess_decrypt_string(tctx, 1334 &blob1, &session_key); 1335 1336 if (strcmp(secret1, secret2) != 0) { 1337 torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n", 1338 secret2, secret1); 1339 ret = false; 1340 } 1341 } 1342 } 1343 1344 enc_key = sess_encrypt_string(secret3, &session_key); 1345 1346 r5.in.sec_handle = &sec_handle; 1347 r5.in.new_val = &buf1; 1348 r5.in.old_val = NULL; 1349 r5.in.new_val->data = enc_key.data; 1350 r5.in.new_val->length = enc_key.length; 1351 r5.in.new_val->size = enc_key.length; 1352 1353 1354 msleep(200); 1355 torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n"); 1356 1357 status = dcerpc_lsa_SetSecret(p, tctx, &r5); 1358 if (!NT_STATUS_IS_OK(status)) { 1359 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status)); 1360 ret = false; 1361 } 1362 1363 data_blob_free(&enc_key); 1364 1365 ZERO_STRUCT(new_mtime); 1366 ZERO_STRUCT(old_mtime); 1367 1368 /* fetch the secret back again */ 1369 r6.in.sec_handle = &sec_handle; 1370 r6.in.new_val = &bufp1; 1371 r6.in.new_mtime = &new_mtime; 1372 r6.in.old_val = &bufp2; 1373 r6.in.old_mtime = &old_mtime; 1374 1375 bufp1.buf = NULL; 1376 bufp2.buf = NULL; 1377 1378 status = dcerpc_lsa_QuerySecret(p, tctx, &r6); 1379 if (!NT_STATUS_IS_OK(status)) { 1380 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status)); 1381 ret = false; 1382 secret4 = NULL; 1383 } else { 1384 1385 if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL 1386 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) { 1387 torture_comment(tctx, "Both secret buffers and both times not returned\n"); 1388 ret = false; 1389 secret4 = NULL; 1390 } else { 1391 blob1.data = r6.out.new_val->buf->data; 1392 blob1.length = r6.out.new_val->buf->size; 1393 1394 blob2 = data_blob_talloc(tctx, NULL, blob1.length); 1395 1396 secret4 = sess_decrypt_string(tctx, 1397 &blob1, &session_key); 1398 1399 if (strcmp(secret3, secret4) != 0) { 1400 torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3); 1401 ret = false; 1402 } 1403 1404 blob1.data = r6.out.old_val->buf->data; 1405 blob1.length = r6.out.old_val->buf->length; 1406 1407 blob2 = data_blob_talloc(tctx, NULL, blob1.length); 1408 1409 secret2 = sess_decrypt_string(tctx, 1410 &blob1, &session_key); 1411 1412 if (strcmp(secret1, secret2) != 0) { 1413 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1); 1414 ret = false; 1415 } 1416 1417 if (*r6.out.new_mtime == *r6.out.old_mtime) { 1418 torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n", 1419 i, 1420 secname[i], 1421 nt_time_string(tctx, *r6.out.old_mtime), 1422 nt_time_string(tctx, *r6.out.new_mtime)); 1423 ret = false; 1424 } 1425 } 1426 } 1427 1428 enc_key = sess_encrypt_string(secret5, &session_key); 1429 1430 r7.in.sec_handle = &sec_handle; 1431 r7.in.old_val = &buf1; 1432 r7.in.old_val->data = enc_key.data; 1433 r7.in.old_val->length = enc_key.length; 1434 r7.in.old_val->size = enc_key.length; 1435 r7.in.new_val = NULL; 1436 1437 torture_comment(tctx, "Testing SetSecret of old Secret only\n"); 1438 1439 status = dcerpc_lsa_SetSecret(p, tctx, &r7); 1440 if (!NT_STATUS_IS_OK(status)) { 1441 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status)); 1442 ret = false; 1443 } 1444 1445 data_blob_free(&enc_key); 1446 1447 /* fetch the secret back again */ 1448 r8.in.sec_handle = &sec_handle; 1449 r8.in.new_val = &bufp1; 1450 r8.in.new_mtime = &new_mtime; 1451 r8.in.old_val = &bufp2; 1452 r8.in.old_mtime = &old_mtime; 1453 1454 bufp1.buf = NULL; 1455 bufp2.buf = NULL; 1456 1457 status = dcerpc_lsa_QuerySecret(p, tctx, &r8); 1458 if (!NT_STATUS_IS_OK(status)) { 1459 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status)); 1460 ret = false; 1461 } else { 1462 if (!r8.out.new_val || !r8.out.old_val) { 1463 torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n"); 1464 ret = false; 1465 } else if (r8.out.new_val->buf != NULL) { 1466 torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n"); 1467 ret = false; 1468 } else if (r8.out.old_val->buf == NULL) { 1469 torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n"); 1470 ret = false; 1471 } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) { 1472 torture_comment(tctx, "Both times not returned after OLD set\n"); 1473 ret = false; 1474 } else { 1475 blob1.data = r8.out.old_val->buf->data; 1476 blob1.length = r8.out.old_val->buf->size; 1477 1478 blob2 = data_blob_talloc(tctx, NULL, blob1.length); 1479 1480 secret6 = sess_decrypt_string(tctx, 1481 &blob1, &session_key); 1482 1483 if (strcmp(secret5, secret6) != 0) { 1484 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6); 1485 ret = false; 1486 } 1487 1488 if (*r8.out.new_mtime != *r8.out.old_mtime) { 1489 torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n", 1490 secname[i], 1491 nt_time_string(tctx, *r8.out.old_mtime), 1492 nt_time_string(tctx, *r8.out.new_mtime)); 1493 ret = false; 1494 } 1495 } 1496 } 1497 1498 if (!test_Delete(p, tctx, &sec_handle)) { 1499 ret = false; 1500 } 1501 1502 if (!test_DeleteObject(p, tctx, &sec_handle)) { 1503 return false; 1504 } 1505 1506 d_o.in.handle = &sec_handle2; 1507 d_o.out.handle = &sec_handle2; 1508 status = dcerpc_lsa_DeleteObject(p, tctx, &d_o); 1509 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { 1510 torture_comment(tctx, "Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status)); 1511 ret = false; 1512 } else { 1513 1514 torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n"); 1515 1516 status = dcerpc_lsa_OpenSecret(p, tctx, &r2); 1517 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1518 torture_comment(tctx, "OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status)); 1519 ret = false; 1520 } 1521 } 1522 1523 } 1524 1525 return ret; 1526} 1527 1528 1529static bool test_EnumAccountRights(struct dcerpc_pipe *p, 1530 struct torture_context *tctx, 1531 struct policy_handle *acct_handle, 1532 struct dom_sid *sid) 1533{ 1534 NTSTATUS status; 1535 struct lsa_EnumAccountRights r; 1536 struct lsa_RightSet rights; 1537 1538 torture_comment(tctx, "\nTesting EnumAccountRights\n"); 1539 1540 r.in.handle = acct_handle; 1541 r.in.sid = sid; 1542 r.out.rights = &rights; 1543 1544 status = dcerpc_lsa_EnumAccountRights(p, tctx, &r); 1545 if (!NT_STATUS_IS_OK(status)) { 1546 torture_comment(tctx, "EnumAccountRights of %s failed - %s\n", 1547 dom_sid_string(tctx, sid), nt_errstr(status)); 1548 return false; 1549 } 1550 1551 return true; 1552} 1553 1554 1555static bool test_QuerySecurity(struct dcerpc_pipe *p, 1556 struct torture_context *tctx, 1557 struct policy_handle *handle, 1558 struct policy_handle *acct_handle) 1559{ 1560 NTSTATUS status; 1561 struct lsa_QuerySecurity r; 1562 struct sec_desc_buf *sdbuf = NULL; 1563 1564 if (torture_setting_bool(tctx, "samba4", false)) { 1565 torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n"); 1566 return true; 1567 } 1568 1569 torture_comment(tctx, "\nTesting QuerySecurity\n"); 1570 1571 r.in.handle = acct_handle; 1572 r.in.sec_info = SECINFO_OWNER | 1573 SECINFO_GROUP | 1574 SECINFO_DACL; 1575 r.out.sdbuf = &sdbuf; 1576 1577 status = dcerpc_lsa_QuerySecurity(p, tctx, &r); 1578 if (!NT_STATUS_IS_OK(status)) { 1579 torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(status)); 1580 return false; 1581 } 1582 1583 return true; 1584} 1585 1586static bool test_OpenAccount(struct dcerpc_pipe *p, 1587 struct torture_context *tctx, 1588 struct policy_handle *handle, 1589 struct dom_sid *sid) 1590{ 1591 NTSTATUS status; 1592 struct lsa_OpenAccount r; 1593 struct policy_handle acct_handle; 1594 1595 torture_comment(tctx, "\nTesting OpenAccount\n"); 1596 1597 r.in.handle = handle; 1598 r.in.sid = sid; 1599 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1600 r.out.acct_handle = &acct_handle; 1601 1602 status = dcerpc_lsa_OpenAccount(p, tctx, &r); 1603 if (!NT_STATUS_IS_OK(status)) { 1604 torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status)); 1605 return false; 1606 } 1607 1608 if (!test_EnumPrivsAccount(p, tctx, handle, &acct_handle)) { 1609 return false; 1610 } 1611 1612 if (!test_GetSystemAccessAccount(p, tctx, handle, &acct_handle)) { 1613 return false; 1614 } 1615 1616 if (!test_QuerySecurity(p, tctx, handle, &acct_handle)) { 1617 return false; 1618 } 1619 1620 return true; 1621} 1622 1623static bool test_EnumAccounts(struct dcerpc_pipe *p, 1624 struct torture_context *tctx, 1625 struct policy_handle *handle) 1626{ 1627 NTSTATUS status; 1628 struct lsa_EnumAccounts r; 1629 struct lsa_SidArray sids1, sids2; 1630 uint32_t resume_handle = 0; 1631 int i; 1632 bool ret = true; 1633 1634 torture_comment(tctx, "\nTesting EnumAccounts\n"); 1635 1636 r.in.handle = handle; 1637 r.in.resume_handle = &resume_handle; 1638 r.in.num_entries = 100; 1639 r.out.resume_handle = &resume_handle; 1640 r.out.sids = &sids1; 1641 1642 resume_handle = 0; 1643 while (true) { 1644 status = dcerpc_lsa_EnumAccounts(p, tctx, &r); 1645 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) { 1646 break; 1647 } 1648 if (!NT_STATUS_IS_OK(status)) { 1649 torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status)); 1650 return false; 1651 } 1652 1653 if (!test_LookupSids(p, tctx, handle, &sids1)) { 1654 return false; 1655 } 1656 1657 if (!test_LookupSids2(p, tctx, handle, &sids1)) { 1658 return false; 1659 } 1660 1661 /* Can't test lookupSids3 here, as clearly we must not 1662 * be on schannel, or we would not be able to do the 1663 * rest */ 1664 1665 torture_comment(tctx, "Testing all accounts\n"); 1666 for (i=0;i<sids1.num_sids;i++) { 1667 ret &= test_OpenAccount(p, tctx, handle, sids1.sids[i].sid); 1668 ret &= test_EnumAccountRights(p, tctx, handle, sids1.sids[i].sid); 1669 } 1670 torture_comment(tctx, "\n"); 1671 } 1672 1673 if (sids1.num_sids < 3) { 1674 return ret; 1675 } 1676 1677 torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n"); 1678 resume_handle = 2; 1679 r.in.num_entries = 1; 1680 r.out.sids = &sids2; 1681 1682 status = dcerpc_lsa_EnumAccounts(p, tctx, &r); 1683 if (!NT_STATUS_IS_OK(status)) { 1684 torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status)); 1685 return false; 1686 } 1687 1688 if (sids2.num_sids != 1) { 1689 torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids); 1690 return false; 1691 } 1692 1693 return true; 1694} 1695 1696static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p, 1697 struct torture_context *tctx, 1698 struct policy_handle *handle, 1699 struct lsa_String *priv_name) 1700{ 1701 struct lsa_LookupPrivDisplayName r; 1702 NTSTATUS status; 1703 /* produce a reasonable range of language output without screwing up 1704 terminals */ 1705 uint16_t language_id = (random() % 4) + 0x409; 1706 uint16_t returned_language_id = 0; 1707 struct lsa_StringLarge *disp_name = NULL; 1708 1709 torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string); 1710 1711 r.in.handle = handle; 1712 r.in.name = priv_name; 1713 r.in.language_id = language_id; 1714 r.in.language_id_sys = 0; 1715 r.out.returned_language_id = &returned_language_id; 1716 r.out.disp_name = &disp_name; 1717 1718 status = dcerpc_lsa_LookupPrivDisplayName(p, tctx, &r); 1719 if (!NT_STATUS_IS_OK(status)) { 1720 torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(status)); 1721 return false; 1722 } 1723 torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n", 1724 priv_name->string, disp_name->string, 1725 r.in.language_id, *r.out.returned_language_id); 1726 1727 return true; 1728} 1729 1730static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, 1731 struct torture_context *tctx, 1732 struct policy_handle *handle, 1733 struct lsa_String *priv_name) 1734{ 1735 struct lsa_EnumAccountsWithUserRight r; 1736 struct lsa_SidArray sids; 1737 NTSTATUS status; 1738 1739 ZERO_STRUCT(sids); 1740 1741 torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string); 1742 1743 r.in.handle = handle; 1744 r.in.name = priv_name; 1745 r.out.sids = &sids; 1746 1747 status = dcerpc_lsa_EnumAccountsWithUserRight(p, tctx, &r); 1748 1749 /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */ 1750 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) { 1751 return true; 1752 } 1753 1754 if (!NT_STATUS_IS_OK(status)) { 1755 torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(status)); 1756 return false; 1757 } 1758 1759 return true; 1760} 1761 1762 1763static bool test_EnumPrivs(struct dcerpc_pipe *p, 1764 struct torture_context *tctx, 1765 struct policy_handle *handle) 1766{ 1767 NTSTATUS status; 1768 struct lsa_EnumPrivs r; 1769 struct lsa_PrivArray privs1; 1770 uint32_t resume_handle = 0; 1771 int i; 1772 bool ret = true; 1773 1774 torture_comment(tctx, "\nTesting EnumPrivs\n"); 1775 1776 r.in.handle = handle; 1777 r.in.resume_handle = &resume_handle; 1778 r.in.max_count = 100; 1779 r.out.resume_handle = &resume_handle; 1780 r.out.privs = &privs1; 1781 1782 resume_handle = 0; 1783 status = dcerpc_lsa_EnumPrivs(p, tctx, &r); 1784 if (!NT_STATUS_IS_OK(status)) { 1785 torture_comment(tctx, "EnumPrivs failed - %s\n", nt_errstr(status)); 1786 return false; 1787 } 1788 1789 for (i = 0; i< privs1.count; i++) { 1790 test_LookupPrivDisplayName(p, tctx, handle, (struct lsa_String *)&privs1.privs[i].name); 1791 test_LookupPrivValue(p, tctx, handle, (struct lsa_String *)&privs1.privs[i].name); 1792 if (!test_EnumAccountsWithUserRight(p, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) { 1793 ret = false; 1794 } 1795 } 1796 1797 return ret; 1798} 1799 1800static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p, 1801 struct torture_context *tctx, 1802 struct policy_handle *handle, 1803 const char *trusted_domain_name) 1804{ 1805 bool ret = true; 1806 struct lsa_lsaRQueryForestTrustInformation r; 1807 NTSTATUS status; 1808 struct lsa_String string; 1809 struct lsa_ForestTrustInformation info, *info_ptr; 1810 1811 torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n"); 1812 1813 if (torture_setting_bool(tctx, "samba4", false)) { 1814 torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n"); 1815 return true; 1816 } 1817 1818 ZERO_STRUCT(string); 1819 1820 if (trusted_domain_name) { 1821 init_lsa_String(&string, trusted_domain_name); 1822 } 1823 1824 info_ptr = &info; 1825 1826 r.in.handle = handle; 1827 r.in.trusted_domain_name = &string; 1828 r.in.unknown = 0; 1829 r.out.forest_trust_info = &info_ptr; 1830 1831 status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r); 1832 1833 if (!NT_STATUS_IS_OK(status)) { 1834 torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status)); 1835 ret = false; 1836 } 1837 1838 return ret; 1839} 1840 1841static bool test_query_each_TrustDomEx(struct dcerpc_pipe *p, 1842 struct torture_context *tctx, 1843 struct policy_handle *handle, 1844 struct lsa_DomainListEx *domains) 1845{ 1846 int i; 1847 bool ret = true; 1848 1849 for (i=0; i< domains->count; i++) { 1850 1851 if (domains->domains[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { 1852 ret &= test_QueryForestTrustInformation(p, tctx, handle, 1853 domains->domains[i].domain_name.string); 1854 } 1855 } 1856 1857 return ret; 1858} 1859 1860static bool test_query_each_TrustDom(struct dcerpc_pipe *p, 1861 struct torture_context *tctx, 1862 struct policy_handle *handle, 1863 struct lsa_DomainList *domains) 1864{ 1865 NTSTATUS status; 1866 int i,j; 1867 bool ret = true; 1868 1869 torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n"); 1870 for (i=0; i< domains->count; i++) { 1871 struct lsa_OpenTrustedDomain trust; 1872 struct lsa_OpenTrustedDomainByName trust_by_name; 1873 struct policy_handle trustdom_handle; 1874 struct policy_handle handle2; 1875 struct lsa_Close c; 1876 struct lsa_CloseTrustedDomainEx c_trust; 1877 int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; 1878 int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1}; 1879 1880 if (domains->domains[i].sid) { 1881 trust.in.handle = handle; 1882 trust.in.sid = domains->domains[i].sid; 1883 trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1884 trust.out.trustdom_handle = &trustdom_handle; 1885 1886 status = dcerpc_lsa_OpenTrustedDomain(p, tctx, &trust); 1887 1888 if (!NT_STATUS_IS_OK(status)) { 1889 torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(status)); 1890 return false; 1891 } 1892 1893 c.in.handle = &trustdom_handle; 1894 c.out.handle = &handle2; 1895 1896 c_trust.in.handle = &trustdom_handle; 1897 c_trust.out.handle = &handle2; 1898 1899 for (j=0; j < ARRAY_SIZE(levels); j++) { 1900 struct lsa_QueryTrustedDomainInfo q; 1901 union lsa_TrustedDomainInfo *info = NULL; 1902 q.in.trustdom_handle = &trustdom_handle; 1903 q.in.level = levels[j]; 1904 q.out.info = &info; 1905 status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); 1906 if (!NT_STATUS_IS_OK(status) && ok[j]) { 1907 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", 1908 levels[j], nt_errstr(status)); 1909 ret = false; 1910 } else if (NT_STATUS_IS_OK(status) && !ok[j]) { 1911 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n", 1912 levels[j], nt_errstr(status)); 1913 ret = false; 1914 } 1915 } 1916 1917 status = dcerpc_lsa_CloseTrustedDomainEx(p, tctx, &c_trust); 1918 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { 1919 torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status)); 1920 return false; 1921 } 1922 1923 c.in.handle = &trustdom_handle; 1924 c.out.handle = &handle2; 1925 1926 status = dcerpc_lsa_Close(p, tctx, &c); 1927 if (!NT_STATUS_IS_OK(status)) { 1928 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status)); 1929 return false; 1930 } 1931 1932 for (j=0; j < ARRAY_SIZE(levels); j++) { 1933 struct lsa_QueryTrustedDomainInfoBySid q; 1934 union lsa_TrustedDomainInfo *info = NULL; 1935 1936 if (!domains->domains[i].sid) { 1937 continue; 1938 } 1939 1940 q.in.handle = handle; 1941 q.in.dom_sid = domains->domains[i].sid; 1942 q.in.level = levels[j]; 1943 q.out.info = &info; 1944 1945 status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q); 1946 if (!NT_STATUS_IS_OK(status) && ok[j]) { 1947 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n", 1948 levels[j], nt_errstr(status)); 1949 ret = false; 1950 } else if (NT_STATUS_IS_OK(status) && !ok[j]) { 1951 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n", 1952 levels[j], nt_errstr(status)); 1953 ret = false; 1954 } 1955 } 1956 } 1957 1958 trust_by_name.in.handle = handle; 1959 trust_by_name.in.name.string = domains->domains[i].name.string; 1960 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1961 trust_by_name.out.trustdom_handle = &trustdom_handle; 1962 1963 status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &trust_by_name); 1964 1965 if (!NT_STATUS_IS_OK(status)) { 1966 torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status)); 1967 return false; 1968 } 1969 1970 for (j=0; j < ARRAY_SIZE(levels); j++) { 1971 struct lsa_QueryTrustedDomainInfo q; 1972 union lsa_TrustedDomainInfo *info = NULL; 1973 q.in.trustdom_handle = &trustdom_handle; 1974 q.in.level = levels[j]; 1975 q.out.info = &info; 1976 status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); 1977 if (!NT_STATUS_IS_OK(status) && ok[j]) { 1978 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", 1979 levels[j], nt_errstr(status)); 1980 ret = false; 1981 } else if (NT_STATUS_IS_OK(status) && !ok[j]) { 1982 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n", 1983 levels[j], nt_errstr(status)); 1984 ret = false; 1985 } 1986 } 1987 1988 c.in.handle = &trustdom_handle; 1989 c.out.handle = &handle2; 1990 1991 status = dcerpc_lsa_Close(p, tctx, &c); 1992 if (!NT_STATUS_IS_OK(status)) { 1993 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status)); 1994 return false; 1995 } 1996 1997 for (j=0; j < ARRAY_SIZE(levels); j++) { 1998 struct lsa_QueryTrustedDomainInfoByName q; 1999 union lsa_TrustedDomainInfo *info = NULL; 2000 struct lsa_String name; 2001 2002 name.string = domains->domains[i].name.string; 2003 2004 q.in.handle = handle; 2005 q.in.trusted_domain = &name; 2006 q.in.level = levels[j]; 2007 q.out.info = &info; 2008 status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, tctx, &q); 2009 if (!NT_STATUS_IS_OK(status) && ok[j]) { 2010 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n", 2011 levels[j], nt_errstr(status)); 2012 ret = false; 2013 } else if (NT_STATUS_IS_OK(status) && !ok[j]) { 2014 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n", 2015 levels[j], nt_errstr(status)); 2016 ret = false; 2017 } 2018 } 2019 } 2020 return ret; 2021} 2022 2023static bool test_EnumTrustDom(struct dcerpc_pipe *p, 2024 struct torture_context *tctx, 2025 struct policy_handle *handle) 2026{ 2027 struct lsa_EnumTrustDom r; 2028 NTSTATUS enum_status; 2029 uint32_t in_resume_handle = 0; 2030 uint32_t out_resume_handle; 2031 struct lsa_DomainList domains; 2032 bool ret = true; 2033 2034 torture_comment(tctx, "\nTesting EnumTrustDom\n"); 2035 2036 r.in.handle = handle; 2037 r.in.resume_handle = &in_resume_handle; 2038 r.in.max_size = 0; 2039 r.out.domains = &domains; 2040 r.out.resume_handle = &out_resume_handle; 2041 2042 enum_status = dcerpc_lsa_EnumTrustDom(p, tctx, &r); 2043 2044 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST 2045 * always be larger than the previous input resume handle, in 2046 * particular when hitting the last query it is vital to set the 2047 * resume handle correctly to avoid infinite client loops, as 2048 * seen e.g. with Windows XP SP3 when resume handle is 0 and 2049 * status is NT_STATUS_OK - gd */ 2050 2051 if (NT_STATUS_IS_OK(enum_status) || 2052 NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES) || 2053 NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) 2054 { 2055 if (out_resume_handle <= in_resume_handle) { 2056 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n", 2057 out_resume_handle, in_resume_handle); 2058 return false; 2059 } 2060 } 2061 2062 if (NT_STATUS_IS_OK(enum_status)) { 2063 if (domains.count == 0) { 2064 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); 2065 return false; 2066 } 2067 } else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) { 2068 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status)); 2069 return false; 2070 } 2071 2072 /* Start from the bottom again */ 2073 in_resume_handle = 0; 2074 2075 do { 2076 r.in.handle = handle; 2077 r.in.resume_handle = &in_resume_handle; 2078 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3; 2079 r.out.domains = &domains; 2080 r.out.resume_handle = &out_resume_handle; 2081 2082 enum_status = dcerpc_lsa_EnumTrustDom(p, tctx, &r); 2083 2084 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST 2085 * always be larger than the previous input resume handle, in 2086 * particular when hitting the last query it is vital to set the 2087 * resume handle correctly to avoid infinite client loops, as 2088 * seen e.g. with Windows XP SP3 when resume handle is 0 and 2089 * status is NT_STATUS_OK - gd */ 2090 2091 if (NT_STATUS_IS_OK(enum_status) || 2092 NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES) || 2093 NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) 2094 { 2095 if (out_resume_handle <= in_resume_handle) { 2096 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n", 2097 out_resume_handle, in_resume_handle); 2098 return false; 2099 } 2100 } 2101 2102 /* NO_MORE_ENTRIES is allowed */ 2103 if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { 2104 if (domains.count == 0) { 2105 return true; 2106 } 2107 torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); 2108 return false; 2109 } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { 2110 /* Windows 2003 gets this off by one on the first run */ 2111 if (r.out.domains->count < 3 || r.out.domains->count > 4) { 2112 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we " 2113 "asked it to (got %d, expected %d / %d == %d entries)\n", 2114 r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3, 2115 LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size); 2116 ret = false; 2117 } 2118 } else if (!NT_STATUS_IS_OK(enum_status)) { 2119 torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(enum_status)); 2120 return false; 2121 } 2122 2123 if (domains.count == 0) { 2124 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); 2125 return false; 2126 } 2127 2128 ret &= test_query_each_TrustDom(p, tctx, handle, &domains); 2129 2130 in_resume_handle = out_resume_handle; 2131 2132 } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))); 2133 2134 return ret; 2135} 2136 2137static bool test_EnumTrustDomEx(struct dcerpc_pipe *p, 2138 struct torture_context *tctx, 2139 struct policy_handle *handle) 2140{ 2141 struct lsa_EnumTrustedDomainsEx r_ex; 2142 NTSTATUS enum_status; 2143 uint32_t resume_handle = 0; 2144 struct lsa_DomainListEx domains_ex; 2145 bool ret = true; 2146 2147 torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n"); 2148 2149 r_ex.in.handle = handle; 2150 r_ex.in.resume_handle = &resume_handle; 2151 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3; 2152 r_ex.out.domains = &domains_ex; 2153 r_ex.out.resume_handle = &resume_handle; 2154 2155 enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex); 2156 2157 if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) { 2158 torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status)); 2159 return false; 2160 } 2161 2162 resume_handle = 0; 2163 do { 2164 r_ex.in.handle = handle; 2165 r_ex.in.resume_handle = &resume_handle; 2166 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3; 2167 r_ex.out.domains = &domains_ex; 2168 r_ex.out.resume_handle = &resume_handle; 2169 2170 enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex); 2171 2172 /* NO_MORE_ENTRIES is allowed */ 2173 if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { 2174 if (domains_ex.count == 0) { 2175 return true; 2176 } 2177 torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); 2178 return false; 2179 } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { 2180 /* Windows 2003 gets this off by one on the first run */ 2181 if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) { 2182 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we " 2183 "asked it to (got %d, expected %d / %d == %d entries)\n", 2184 r_ex.out.domains->count, 2185 r_ex.in.max_size, 2186 LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER, 2187 r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER); 2188 } 2189 } else if (!NT_STATUS_IS_OK(enum_status)) { 2190 torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status)); 2191 return false; 2192 } 2193 2194 if (domains_ex.count == 0) { 2195 torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n"); 2196 return false; 2197 } 2198 2199 ret &= test_query_each_TrustDomEx(p, tctx, handle, &domains_ex); 2200 2201 } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))); 2202 2203 return ret; 2204} 2205 2206 2207static bool test_CreateTrustedDomain(struct dcerpc_pipe *p, 2208 struct torture_context *tctx, 2209 struct policy_handle *handle, 2210 uint32_t num_trusts) 2211{ 2212 NTSTATUS status; 2213 bool ret = true; 2214 struct lsa_CreateTrustedDomain r; 2215 struct lsa_DomainInfo trustinfo; 2216 struct dom_sid **domsid; 2217 struct policy_handle *trustdom_handle; 2218 struct lsa_QueryTrustedDomainInfo q; 2219 union lsa_TrustedDomainInfo *info = NULL; 2220 int i; 2221 2222 torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts); 2223 2224 if (!test_EnumTrustDom(p, tctx, handle)) { 2225 ret = false; 2226 } 2227 2228 if (!test_EnumTrustDomEx(p, tctx, handle)) { 2229 ret = false; 2230 } 2231 2232 domsid = talloc_array(tctx, struct dom_sid *, num_trusts); 2233 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts); 2234 2235 for (i=0; i< num_trusts; i++) { 2236 char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i); 2237 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i); 2238 2239 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid); 2240 2241 trustinfo.sid = domsid[i]; 2242 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name); 2243 2244 r.in.policy_handle = handle; 2245 r.in.info = &trustinfo; 2246 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 2247 r.out.trustdom_handle = &trustdom_handle[i]; 2248 2249 status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r); 2250 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { 2251 test_DeleteTrustedDomain(p, tctx, handle, trustinfo.name); 2252 status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r); 2253 } 2254 if (!NT_STATUS_IS_OK(status)) { 2255 torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(status)); 2256 ret = false; 2257 } else { 2258 2259 q.in.trustdom_handle = &trustdom_handle[i]; 2260 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX; 2261 q.out.info = &info; 2262 status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); 2263 if (!NT_STATUS_IS_OK(status)) { 2264 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(status)); 2265 ret = false; 2266 } else if (!q.out.info) { 2267 ret = false; 2268 } else { 2269 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) { 2270 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", 2271 info->info_ex.netbios_name.string, trustinfo.name.string); 2272 ret = false; 2273 } 2274 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) { 2275 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", 2276 trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL); 2277 ret = false; 2278 } 2279 if (info->info_ex.trust_attributes != 0) { 2280 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", 2281 trust_name, info->info_ex.trust_attributes, 0); 2282 ret = false; 2283 } 2284 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) { 2285 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", 2286 trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND); 2287 ret = false; 2288 } 2289 } 2290 } 2291 } 2292 2293 /* now that we have some domains to look over, we can test the enum calls */ 2294 if (!test_EnumTrustDom(p, tctx, handle)) { 2295 ret = false; 2296 } 2297 2298 if (!test_EnumTrustDomEx(p, tctx, handle)) { 2299 ret = false; 2300 } 2301 2302 for (i=0; i<num_trusts; i++) { 2303 if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) { 2304 ret = false; 2305 } 2306 } 2307 2308 return ret; 2309} 2310 2311static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, 2312 struct torture_context *tctx, 2313 struct policy_handle *handle, 2314 uint32_t num_trusts) 2315{ 2316 NTSTATUS status; 2317 bool ret = true; 2318 struct lsa_CreateTrustedDomainEx2 r; 2319 struct lsa_TrustDomainInfoInfoEx trustinfo; 2320 struct lsa_TrustDomainInfoAuthInfoInternal authinfo; 2321 struct trustDomainPasswords auth_struct; 2322 DATA_BLOB auth_blob; 2323 struct dom_sid **domsid; 2324 struct policy_handle *trustdom_handle; 2325 struct lsa_QueryTrustedDomainInfo q; 2326 union lsa_TrustedDomainInfo *info = NULL; 2327 DATA_BLOB session_key; 2328 enum ndr_err_code ndr_err; 2329 int i; 2330 2331 torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts); 2332 2333 domsid = talloc_array(tctx, struct dom_sid *, num_trusts); 2334 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts); 2335 2336 status = dcerpc_fetch_session_key(p, &session_key); 2337 if (!NT_STATUS_IS_OK(status)) { 2338 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status)); 2339 return false; 2340 } 2341 2342 for (i=0; i< num_trusts; i++) { 2343 char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i); 2344 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%02d.samba.example.com", i); 2345 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i); 2346 2347 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid); 2348 2349 trustinfo.sid = domsid[i]; 2350 trustinfo.netbios_name.string = trust_name; 2351 trustinfo.domain_name.string = trust_name_dns; 2352 2353 /* Create inbound, some outbound, and some 2354 * bi-directional trusts in a repeating pattern based 2355 * on i */ 2356 2357 /* 1 == inbound, 2 == outbound, 3 == both */ 2358 trustinfo.trust_direction = (i % 3) + 1; 2359 2360 /* Try different trust types too */ 2361 2362 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */ 2363 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1; 2364 2365 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION; 2366 2367 generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder)); 2368 2369 auth_struct.outgoing.count = 0; 2370 auth_struct.incoming.count = 0; 2371 2372 ndr_err = ndr_push_struct_blob(&auth_blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct, 2373 (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); 2374 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 2375 torture_comment(tctx, "ndr_push_struct_blob of trustDomainPasswords structure failed"); 2376 ret = false; 2377 } 2378 2379 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key); 2380 2381 authinfo.auth_blob.size = auth_blob.length; 2382 authinfo.auth_blob.data = auth_blob.data; 2383 2384 r.in.policy_handle = handle; 2385 r.in.info = &trustinfo; 2386 r.in.auth_info = &authinfo; 2387 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 2388 r.out.trustdom_handle = &trustdom_handle[i]; 2389 2390 status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r); 2391 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { 2392 test_DeleteTrustedDomain(p, tctx, handle, trustinfo.netbios_name); 2393 status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r); 2394 } 2395 if (!NT_STATUS_IS_OK(status)) { 2396 torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status)); 2397 ret = false; 2398 } else { 2399 2400 q.in.trustdom_handle = &trustdom_handle[i]; 2401 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX; 2402 q.out.info = &info; 2403 status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q); 2404 if (!NT_STATUS_IS_OK(status)) { 2405 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); 2406 ret = false; 2407 } else if (!q.out.info) { 2408 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n"); 2409 ret = false; 2410 } else { 2411 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) { 2412 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n", 2413 info->info_ex.netbios_name.string, trustinfo.netbios_name.string); 2414 ret = false; 2415 } 2416 if (info->info_ex.trust_type != trustinfo.trust_type) { 2417 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n", 2418 trust_name, info->info_ex.trust_type, trustinfo.trust_type); 2419 ret = false; 2420 } 2421 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) { 2422 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n", 2423 trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION); 2424 ret = false; 2425 } 2426 if (info->info_ex.trust_direction != trustinfo.trust_direction) { 2427 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n", 2428 trust_name, info->info_ex.trust_direction, trustinfo.trust_direction); 2429 ret = false; 2430 } 2431 } 2432 } 2433 } 2434 2435 /* now that we have some domains to look over, we can test the enum calls */ 2436 if (!test_EnumTrustDom(p, tctx, handle)) { 2437 torture_comment(tctx, "test_EnumTrustDom failed\n"); 2438 ret = false; 2439 } 2440 2441 if (!test_EnumTrustDomEx(p, tctx, handle)) { 2442 torture_comment(tctx, "test_EnumTrustDomEx failed\n"); 2443 ret = false; 2444 } 2445 2446 for (i=0; i<num_trusts; i++) { 2447 if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) { 2448 torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n"); 2449 ret = false; 2450 } 2451 } 2452 2453 return ret; 2454} 2455 2456static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, 2457 struct torture_context *tctx, 2458 struct policy_handle *handle) 2459{ 2460 struct lsa_QueryDomainInformationPolicy r; 2461 union lsa_DomainInformationPolicy *info = NULL; 2462 NTSTATUS status; 2463 int i; 2464 bool ret = true; 2465 2466 if (torture_setting_bool(tctx, "samba3", false)) { 2467 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n"); 2468 } 2469 2470 torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n"); 2471 2472 for (i=2;i<4;i++) { 2473 r.in.handle = handle; 2474 r.in.level = i; 2475 r.out.info = &info; 2476 2477 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i); 2478 2479 status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r); 2480 2481 /* If the server does not support EFS, then this is the correct return */ 2482 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 2483 continue; 2484 } else if (!NT_STATUS_IS_OK(status)) { 2485 torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(status)); 2486 ret = false; 2487 continue; 2488 } 2489 } 2490 2491 return ret; 2492} 2493 2494 2495static bool test_QueryInfoPolicyCalls( bool version2, 2496 struct dcerpc_pipe *p, 2497 struct torture_context *tctx, 2498 struct policy_handle *handle) 2499{ 2500 struct lsa_QueryInfoPolicy r; 2501 union lsa_PolicyInformation *info = NULL; 2502 NTSTATUS status; 2503 int i; 2504 bool ret = true; 2505 const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":""); 2506 2507 torture_comment(tctx, "\nTesting %s\n", call); 2508 2509 if (version2 && torture_setting_bool(tctx, "samba3", false)) { 2510 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n"); 2511 } 2512 2513 for (i=1;i<=14;i++) { 2514 r.in.handle = handle; 2515 r.in.level = i; 2516 r.out.info = &info; 2517 2518 torture_comment(tctx, "\nTrying %s level %d\n", call, i); 2519 2520 if (version2) 2521 /* We can perform the cast, because both types are 2522 structurally equal */ 2523 status = dcerpc_lsa_QueryInfoPolicy2(p, tctx, 2524 (struct lsa_QueryInfoPolicy2*) &r); 2525 else 2526 status = dcerpc_lsa_QueryInfoPolicy(p, tctx, &r); 2527 2528 switch (i) { 2529 case LSA_POLICY_INFO_MOD: 2530 case LSA_POLICY_INFO_AUDIT_FULL_SET: 2531 case LSA_POLICY_INFO_AUDIT_FULL_QUERY: 2532 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { 2533 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(status)); 2534 ret = false; 2535 } 2536 break; 2537 case LSA_POLICY_INFO_DOMAIN: 2538 case LSA_POLICY_INFO_ACCOUNT_DOMAIN: 2539 case LSA_POLICY_INFO_REPLICA: 2540 case LSA_POLICY_INFO_QUOTA: 2541 case LSA_POLICY_INFO_ROLE: 2542 case LSA_POLICY_INFO_AUDIT_LOG: 2543 case LSA_POLICY_INFO_AUDIT_EVENTS: 2544 case LSA_POLICY_INFO_PD: 2545 if (!NT_STATUS_IS_OK(status)) { 2546 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status)); 2547 ret = false; 2548 } 2549 break; 2550 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN: 2551 case LSA_POLICY_INFO_DNS_INT: 2552 case LSA_POLICY_INFO_DNS: 2553 if (torture_setting_bool(tctx, "samba3", false)) { 2554 /* Other levels not implemented yet */ 2555 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) { 2556 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status)); 2557 ret = false; 2558 } 2559 } else if (!NT_STATUS_IS_OK(status)) { 2560 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status)); 2561 ret = false; 2562 } 2563 break; 2564 default: 2565 if (torture_setting_bool(tctx, "samba4", false)) { 2566 /* Other levels not implemented yet */ 2567 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) { 2568 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status)); 2569 ret = false; 2570 } 2571 } else if (!NT_STATUS_IS_OK(status)) { 2572 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status)); 2573 ret = false; 2574 } 2575 break; 2576 } 2577 2578 if (NT_STATUS_IS_OK(status) && (i == LSA_POLICY_INFO_DNS 2579 || i == LSA_POLICY_INFO_DNS_INT)) { 2580 /* Let's look up some of these names */ 2581 2582 struct lsa_TransNameArray tnames; 2583 tnames.count = 14; 2584 tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count); 2585 tnames.names[0].name.string = info->dns.name.string; 2586 tnames.names[0].sid_type = SID_NAME_DOMAIN; 2587 tnames.names[1].name.string = info->dns.dns_domain.string; 2588 tnames.names[1].sid_type = SID_NAME_DOMAIN; 2589 tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string); 2590 tnames.names[2].sid_type = SID_NAME_DOMAIN; 2591 tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string); 2592 tnames.names[3].sid_type = SID_NAME_DOMAIN; 2593 tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string); 2594 tnames.names[4].sid_type = SID_NAME_USER; 2595 tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string); 2596 tnames.names[5].sid_type = SID_NAME_USER; 2597 tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string); 2598 tnames.names[6].sid_type = SID_NAME_USER; 2599 tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string); 2600 tnames.names[7].sid_type = SID_NAME_USER; 2601 tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string); 2602 tnames.names[8].sid_type = SID_NAME_USER; 2603 tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string); 2604 tnames.names[9].sid_type = SID_NAME_USER; 2605 tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string); 2606 tnames.names[10].sid_type = SID_NAME_USER; 2607 tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string); 2608 tnames.names[11].sid_type = SID_NAME_USER; 2609 tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string); 2610 tnames.names[12].sid_type = SID_NAME_USER; 2611 tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string); 2612 tnames.names[13].sid_type = SID_NAME_USER; 2613 ret &= test_LookupNames(p, tctx, handle, &tnames); 2614 2615 } 2616 } 2617 2618 return ret; 2619} 2620 2621static bool test_QueryInfoPolicy(struct dcerpc_pipe *p, 2622 struct torture_context *tctx, 2623 struct policy_handle *handle) 2624{ 2625 return test_QueryInfoPolicyCalls(false, p, tctx, handle); 2626} 2627 2628static bool test_QueryInfoPolicy2(struct dcerpc_pipe *p, 2629 struct torture_context *tctx, 2630 struct policy_handle *handle) 2631{ 2632 return test_QueryInfoPolicyCalls(true, p, tctx, handle); 2633} 2634 2635static bool test_GetUserName(struct dcerpc_pipe *p, 2636 struct torture_context *tctx) 2637{ 2638 struct lsa_GetUserName r; 2639 NTSTATUS status; 2640 bool ret = true; 2641 struct lsa_String *authority_name_p = NULL; 2642 struct lsa_String *account_name_p = NULL; 2643 2644 torture_comment(tctx, "\nTesting GetUserName\n"); 2645 2646 r.in.system_name = "\\"; 2647 r.in.account_name = &account_name_p; 2648 r.in.authority_name = NULL; 2649 r.out.account_name = &account_name_p; 2650 2651 status = dcerpc_lsa_GetUserName(p, tctx, &r); 2652 2653 if (!NT_STATUS_IS_OK(status)) { 2654 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status)); 2655 ret = false; 2656 } 2657 2658 account_name_p = NULL; 2659 r.in.account_name = &account_name_p; 2660 r.in.authority_name = &authority_name_p; 2661 r.out.account_name = &account_name_p; 2662 2663 status = dcerpc_lsa_GetUserName(p, tctx, &r); 2664 2665 if (!NT_STATUS_IS_OK(status)) { 2666 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status)); 2667 ret = false; 2668 } 2669 2670 return ret; 2671} 2672 2673bool test_lsa_Close(struct dcerpc_pipe *p, 2674 struct torture_context *tctx, 2675 struct policy_handle *handle) 2676{ 2677 NTSTATUS status; 2678 struct lsa_Close r; 2679 struct policy_handle handle2; 2680 2681 torture_comment(tctx, "\nTesting Close\n"); 2682 2683 r.in.handle = handle; 2684 r.out.handle = &handle2; 2685 2686 status = dcerpc_lsa_Close(p, tctx, &r); 2687 if (!NT_STATUS_IS_OK(status)) { 2688 torture_comment(tctx, "Close failed - %s\n", nt_errstr(status)); 2689 return false; 2690 } 2691 2692 status = dcerpc_lsa_Close(p, tctx, &r); 2693 /* its really a fault - we need a status code for rpc fault */ 2694 if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { 2695 torture_comment(tctx, "Close failed - %s\n", nt_errstr(status)); 2696 return false; 2697 } 2698 2699 torture_comment(tctx, "\n"); 2700 2701 return true; 2702} 2703 2704bool torture_rpc_lsa(struct torture_context *tctx) 2705{ 2706 NTSTATUS status; 2707 struct dcerpc_pipe *p; 2708 bool ret = true; 2709 struct policy_handle *handle; 2710 struct test_join *join = NULL; 2711 struct cli_credentials *machine_creds; 2712 2713 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc); 2714 if (!NT_STATUS_IS_OK(status)) { 2715 return false; 2716 } 2717 2718 if (!test_OpenPolicy(p, tctx)) { 2719 ret = false; 2720 } 2721 2722 if (!test_lsa_OpenPolicy2(p, tctx, &handle)) { 2723 ret = false; 2724 } 2725 2726 if (handle) { 2727 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds); 2728 if (!join) { 2729 ret = false; 2730 } 2731 2732 if (!test_LookupSids_async(p, tctx, handle)) { 2733 ret = false; 2734 } 2735 2736 if (!test_QueryDomainInfoPolicy(p, tctx, handle)) { 2737 ret = false; 2738 } 2739 2740 if (!test_CreateSecret(p, tctx, handle)) { 2741 ret = false; 2742 } 2743 2744 if (!test_QueryInfoPolicy(p, tctx, handle)) { 2745 ret = false; 2746 } 2747 2748 if (!test_QueryInfoPolicy2(p, tctx, handle)) { 2749 ret = false; 2750 } 2751 2752 if (!test_Delete(p, tctx, handle)) { 2753 ret = false; 2754 } 2755 2756 if (!test_many_LookupSids(p, tctx, handle)) { 2757 ret = false; 2758 } 2759 2760 if (!test_lsa_Close(p, tctx, handle)) { 2761 ret = false; 2762 } 2763 2764 torture_leave_domain(tctx, join); 2765 2766 } else { 2767 if (!test_many_LookupSids(p, tctx, handle)) { 2768 ret = false; 2769 } 2770 } 2771 2772 if (!test_GetUserName(p, tctx)) { 2773 ret = false; 2774 } 2775 2776 return ret; 2777} 2778 2779bool torture_rpc_lsa_get_user(struct torture_context *tctx) 2780{ 2781 NTSTATUS status; 2782 struct dcerpc_pipe *p; 2783 bool ret = true; 2784 2785 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc); 2786 if (!NT_STATUS_IS_OK(status)) { 2787 return false; 2788 } 2789 2790 if (!test_GetUserName(p, tctx)) { 2791 ret = false; 2792 } 2793 2794 return ret; 2795} 2796 2797static bool testcase_LookupNames(struct torture_context *tctx, 2798 struct dcerpc_pipe *p) 2799{ 2800 bool ret = true; 2801 struct policy_handle *handle; 2802 struct lsa_TransNameArray tnames; 2803 struct lsa_TransNameArray2 tnames2; 2804 2805 if (!test_OpenPolicy(p, tctx)) { 2806 ret = false; 2807 } 2808 2809 if (!test_lsa_OpenPolicy2(p, tctx, &handle)) { 2810 ret = false; 2811 } 2812 2813 if (!handle) { 2814 ret = false; 2815 } 2816 2817 tnames.count = 1; 2818 tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count); 2819 ZERO_STRUCT(tnames.names[0]); 2820 tnames.names[0].name.string = "BUILTIN"; 2821 tnames.names[0].sid_type = SID_NAME_DOMAIN; 2822 2823 if (!test_LookupNames(p, tctx, handle, &tnames)) { 2824 ret = false; 2825 } 2826 2827 tnames2.count = 1; 2828 tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count); 2829 ZERO_STRUCT(tnames2.names[0]); 2830 tnames2.names[0].name.string = "BUILTIN"; 2831 tnames2.names[0].sid_type = SID_NAME_DOMAIN; 2832 2833 if (!test_LookupNames2(p, tctx, handle, &tnames2, true)) { 2834 ret = false; 2835 } 2836 2837 if (!test_LookupNames3(p, tctx, handle, &tnames2, true)) { 2838 ret = false; 2839 } 2840 2841 if (!test_LookupNames_wellknown(p, tctx, handle)) { 2842 ret = false; 2843 } 2844 2845 if (!test_LookupNames_NULL(p, tctx, handle)) { 2846 ret = false; 2847 } 2848 2849 if (!test_LookupNames_bogus(p, tctx, handle)) { 2850 ret = false; 2851 } 2852 2853 if (!test_lsa_Close(p, tctx, handle)) { 2854 ret = false; 2855 } 2856 2857 return ret; 2858} 2859 2860struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx) 2861{ 2862 struct torture_suite *suite; 2863 struct torture_rpc_tcase *tcase; 2864 2865 suite = torture_suite_create(mem_ctx, "LSA-LOOKUPNAMES"); 2866 2867 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", 2868 &ndr_table_lsarpc); 2869 torture_rpc_tcase_add_test(tcase, "LookupNames", 2870 testcase_LookupNames); 2871 2872 return suite; 2873} 2874 2875struct lsa_trustdom_state { 2876 uint32_t num_trusts; 2877}; 2878 2879static bool testcase_TrustedDomains(struct torture_context *tctx, 2880 struct dcerpc_pipe *p, 2881 void *data) 2882{ 2883 bool ret = true; 2884 struct policy_handle *handle; 2885 struct lsa_trustdom_state *state = 2886 talloc_get_type_abort(data, struct lsa_trustdom_state); 2887 2888 torture_comment(tctx, "testing %d domains\n", state->num_trusts); 2889 2890 if (!test_OpenPolicy(p, tctx)) { 2891 ret = false; 2892 } 2893 2894 if (!test_lsa_OpenPolicy2(p, tctx, &handle)) { 2895 ret = false; 2896 } 2897 2898 if (!handle) { 2899 ret = false; 2900 } 2901 2902 if (!test_CreateTrustedDomain(p, tctx, handle, state->num_trusts)) { 2903 ret = false; 2904 } 2905 2906 if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) { 2907 ret = false; 2908 } 2909 2910 if (!test_lsa_Close(p, tctx, handle)) { 2911 ret = false; 2912 } 2913 2914 return ret; 2915} 2916 2917struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx) 2918{ 2919 struct torture_suite *suite; 2920 struct torture_rpc_tcase *tcase; 2921 struct lsa_trustdom_state *state; 2922 2923 state = talloc(mem_ctx, struct lsa_trustdom_state); 2924 2925 state->num_trusts = 12; 2926 2927 suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS"); 2928 2929 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", 2930 &ndr_table_lsarpc); 2931 torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains", 2932 testcase_TrustedDomains, 2933 state); 2934 2935 return suite; 2936} 2937 2938static bool testcase_Privileges(struct torture_context *tctx, 2939 struct dcerpc_pipe *p) 2940{ 2941 bool ret = true; 2942 struct policy_handle *handle; 2943 2944 if (!test_OpenPolicy(p, tctx)) { 2945 ret = false; 2946 } 2947 2948 if (!test_lsa_OpenPolicy2(p, tctx, &handle)) { 2949 ret = false; 2950 } 2951 2952 if (!handle) { 2953 ret = false; 2954 } 2955 2956 if (!test_CreateAccount(p, tctx, handle)) { 2957 ret = false; 2958 } 2959 2960 if (!test_EnumAccounts(p, tctx, handle)) { 2961 ret = false; 2962 } 2963 2964 if (!test_EnumPrivs(p, tctx, handle)) { 2965 ret = false; 2966 } 2967 2968 if (!test_lsa_Close(p, tctx, handle)) { 2969 ret = false; 2970 } 2971 2972 return ret; 2973} 2974 2975 2976struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx) 2977{ 2978 struct torture_suite *suite; 2979 struct torture_rpc_tcase *tcase; 2980 2981 suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES"); 2982 2983 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa", 2984 &ndr_table_lsarpc); 2985 torture_rpc_tcase_add_test(tcase, "Privileges", 2986 testcase_Privileges); 2987 2988 return suite; 2989} 2990