1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: Security Account Manager (SAM) Server 4 * FILE: reactos/dll/win32/samsrv/setup.c 5 * PURPOSE: Registry setup routines 6 * 7 * PROGRAMMERS: Eric Kohl 8 */ 9 10 /* INCLUDES ****************************************************************/ 11 12 #include "samsrv.h" 13 14 WINE_DEFAULT_DEBUG_CHANNEL(samsrv); 15 16 17 /* GLOBALS *****************************************************************/ 18 19 #define TICKS_PER_SECOND 10000000LL 20 21 SID_IDENTIFIER_AUTHORITY SecurityNtAuthority = {SECURITY_NT_AUTHORITY}; 22 23 24 /* FUNCTIONS ***************************************************************/ 25 26 static BOOL 27 SampSetupAddMemberToAlias(HKEY hDomainKey, 28 ULONG AliasId, 29 PSID MemberSid) 30 { 31 DWORD dwDisposition; 32 LPWSTR MemberSidString = NULL; 33 WCHAR szKeyName[256]; 34 HKEY hMembersKey; 35 36 ConvertSidToStringSidW(MemberSid, &MemberSidString); 37 38 swprintf(szKeyName, L"Aliases\\%08lX\\Members", AliasId); 39 40 if (!RegCreateKeyExW(hDomainKey, 41 szKeyName, 42 0, 43 NULL, 44 REG_OPTION_NON_VOLATILE, 45 KEY_ALL_ACCESS, 46 NULL, 47 &hMembersKey, 48 &dwDisposition)) 49 { 50 RegSetValueEx(hMembersKey, 51 MemberSidString, 52 0, 53 REG_BINARY, 54 (LPVOID)MemberSid, 55 RtlLengthSid(MemberSid)); 56 57 RegCloseKey(hMembersKey); 58 } 59 60 swprintf(szKeyName, L"Aliases\\Members\\%s", MemberSidString); 61 62 if (!RegCreateKeyExW(hDomainKey, 63 szKeyName, 64 0, 65 NULL, 66 REG_OPTION_NON_VOLATILE, 67 KEY_ALL_ACCESS, 68 NULL, 69 &hMembersKey, 70 &dwDisposition)) 71 { 72 swprintf(szKeyName, L"%08lX", AliasId); 73 74 RegSetValueEx(hMembersKey, 75 szKeyName, 76 0, 77 REG_BINARY, 78 (LPVOID)MemberSid, 79 RtlLengthSid(MemberSid)); 80 81 RegCloseKey(hMembersKey); 82 } 83 84 if (MemberSidString != NULL) 85 LocalFree(MemberSidString); 86 87 return TRUE; 88 } 89 90 91 static 92 NTSTATUS 93 SampSetupCreateAliasAccount(HANDLE hDomainKey, 94 LPCWSTR lpAccountName, 95 LPCWSTR lpDescription, 96 ULONG ulRelativeId) 97 { 98 WCHAR szAccountKeyName[32]; 99 HANDLE hAccountKey = NULL; 100 HANDLE hNamesKey = NULL; 101 NTSTATUS Status; 102 103 swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId); 104 105 Status = SampRegCreateKey(hDomainKey, 106 szAccountKeyName, 107 KEY_ALL_ACCESS, 108 &hAccountKey); 109 if (!NT_SUCCESS(Status)) 110 return Status; 111 112 Status = SampRegSetValue(hAccountKey, 113 L"Name", 114 REG_SZ, 115 (LPVOID)lpAccountName, 116 (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); 117 if (!NT_SUCCESS(Status)) 118 goto done; 119 120 Status = SampRegSetValue(hAccountKey, 121 L"Description", 122 REG_SZ, 123 (LPVOID)lpDescription, 124 (wcslen(lpDescription) + 1) * sizeof(WCHAR)); 125 if (!NT_SUCCESS(Status)) 126 goto done; 127 128 129 Status = SampRegOpenKey(hDomainKey, 130 L"Aliases\\Names", 131 KEY_ALL_ACCESS, 132 &hNamesKey); 133 if (!NT_SUCCESS(Status)) 134 goto done; 135 136 Status = SampRegSetValue(hNamesKey, 137 lpAccountName, 138 REG_DWORD, 139 (LPVOID)&ulRelativeId, 140 sizeof(ULONG)); 141 142 done: 143 if (hNamesKey != NULL) 144 SampRegCloseKey(hNamesKey); 145 146 if (hAccountKey != NULL) 147 { 148 SampRegCloseKey(hAccountKey); 149 150 if (!NT_SUCCESS(Status)) 151 SampRegDeleteKey(hDomainKey, 152 szAccountKeyName); 153 } 154 155 return Status; 156 } 157 158 159 static 160 NTSTATUS 161 SampSetupAddMemberToGroup(IN HANDLE hDomainKey, 162 IN ULONG GroupId, 163 IN ULONG MemberId) 164 { 165 WCHAR szKeyName[256]; 166 HANDLE hGroupKey = NULL; 167 PULONG MembersBuffer = NULL; 168 ULONG MembersCount = 0; 169 ULONG Length = 0; 170 ULONG i; 171 NTSTATUS Status; 172 173 swprintf(szKeyName, L"Groups\\%08lX", GroupId); 174 175 Status = SampRegOpenKey(hDomainKey, 176 szKeyName, 177 KEY_ALL_ACCESS, 178 &hGroupKey); 179 if (!NT_SUCCESS(Status)) 180 return Status; 181 182 Status = SampRegQueryValue(hGroupKey, 183 L"Members", 184 NULL, 185 NULL, 186 &Length); 187 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) 188 goto done; 189 190 MembersBuffer = midl_user_allocate(Length + sizeof(ULONG)); 191 if (MembersBuffer == NULL) 192 { 193 Status = STATUS_INSUFFICIENT_RESOURCES; 194 goto done; 195 } 196 197 if (Status != STATUS_OBJECT_NAME_NOT_FOUND) 198 { 199 Status = SampRegQueryValue(hGroupKey, 200 L"Members", 201 NULL, 202 MembersBuffer, 203 &Length); 204 if (!NT_SUCCESS(Status)) 205 goto done; 206 207 MembersCount = Length / sizeof(ULONG); 208 } 209 210 for (i = 0; i < MembersCount; i++) 211 { 212 if (MembersBuffer[i] == MemberId) 213 { 214 Status = STATUS_MEMBER_IN_GROUP; 215 goto done; 216 } 217 } 218 219 MembersBuffer[MembersCount] = MemberId; 220 Length += sizeof(ULONG); 221 222 Status = SampRegSetValue(hGroupKey, 223 L"Members", 224 REG_BINARY, 225 MembersBuffer, 226 Length); 227 228 done: 229 if (MembersBuffer != NULL) 230 midl_user_free(MembersBuffer); 231 232 if (hGroupKey != NULL) 233 SampRegCloseKey(hGroupKey); 234 235 return Status; 236 } 237 238 239 static 240 NTSTATUS 241 SampSetupCreateGroupAccount(HANDLE hDomainKey, 242 LPCWSTR lpAccountName, 243 LPCWSTR lpComment, 244 ULONG ulRelativeId) 245 { 246 SAM_GROUP_FIXED_DATA FixedGroupData; 247 WCHAR szAccountKeyName[32]; 248 HANDLE hAccountKey = NULL; 249 HANDLE hNamesKey = NULL; 250 NTSTATUS Status; 251 252 /* Initialize fixed group data */ 253 FixedGroupData.Version = 1; 254 FixedGroupData.Reserved = 0; 255 FixedGroupData.GroupId = ulRelativeId; 256 FixedGroupData.Attributes = 0; 257 258 swprintf(szAccountKeyName, L"Groups\\%08lX", ulRelativeId); 259 260 Status = SampRegCreateKey(hDomainKey, 261 szAccountKeyName, 262 KEY_ALL_ACCESS, 263 &hAccountKey); 264 if (!NT_SUCCESS(Status)) 265 return Status; 266 267 Status = SampRegSetValue(hAccountKey, 268 L"F", 269 REG_BINARY, 270 (LPVOID)&FixedGroupData, 271 sizeof(SAM_GROUP_FIXED_DATA)); 272 if (!NT_SUCCESS(Status)) 273 goto done; 274 275 Status = SampRegSetValue(hAccountKey, 276 L"Name", 277 REG_SZ, 278 (LPVOID)lpAccountName, 279 (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); 280 if (!NT_SUCCESS(Status)) 281 goto done; 282 283 Status = SampRegSetValue(hAccountKey, 284 L"AdminComment", 285 REG_SZ, 286 (LPVOID)lpComment, 287 (wcslen(lpComment) + 1) * sizeof(WCHAR)); 288 if (!NT_SUCCESS(Status)) 289 goto done; 290 291 Status = SampRegOpenKey(hDomainKey, 292 L"Groups\\Names", 293 KEY_ALL_ACCESS, 294 &hNamesKey); 295 if (!NT_SUCCESS(Status)) 296 goto done; 297 298 Status = SampRegSetValue(hNamesKey, 299 lpAccountName, 300 REG_DWORD, 301 (LPVOID)&ulRelativeId, 302 sizeof(ULONG)); 303 304 done: 305 if (hNamesKey != NULL) 306 SampRegCloseKey(hNamesKey); 307 308 if (hAccountKey != NULL) 309 { 310 SampRegCloseKey(hAccountKey); 311 312 if (!NT_SUCCESS(Status)) 313 SampRegDeleteKey(hDomainKey, 314 szAccountKeyName); 315 } 316 317 return Status; 318 } 319 320 321 static 322 NTSTATUS 323 SampSetupCreateUserAccount(HANDLE hDomainKey, 324 LPCWSTR lpAccountName, 325 LPCWSTR lpComment, 326 ULONG ulRelativeId, 327 ULONG UserAccountControl) 328 { 329 SAM_USER_FIXED_DATA FixedUserData; 330 GROUP_MEMBERSHIP GroupMembership; 331 UCHAR LogonHours[23]; 332 LPWSTR lpEmptyString = L""; 333 WCHAR szAccountKeyName[32]; 334 HANDLE hAccountKey = NULL; 335 HANDLE hNamesKey = NULL; 336 NTSTATUS Status; 337 338 /* Initialize fixed user data */ 339 FixedUserData.Version = 1; 340 FixedUserData.Reserved = 0; 341 FixedUserData.LastLogon.QuadPart = 0; 342 FixedUserData.LastLogoff.QuadPart = 0; 343 FixedUserData.PasswordLastSet.QuadPart = 0; 344 FixedUserData.AccountExpires.LowPart = MAXULONG; 345 FixedUserData.AccountExpires.HighPart = MAXLONG; 346 FixedUserData.LastBadPasswordTime.QuadPart = 0; 347 FixedUserData.UserId = ulRelativeId; 348 FixedUserData.PrimaryGroupId = DOMAIN_GROUP_RID_USERS; 349 FixedUserData.UserAccountControl = UserAccountControl; 350 FixedUserData.CountryCode = 0; 351 FixedUserData.CodePage = 0; 352 FixedUserData.BadPasswordCount = 0; 353 FixedUserData.LogonCount = 0; 354 FixedUserData.AdminCount = 0; 355 FixedUserData.OperatorCount = 0; 356 357 swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId); 358 359 Status = SampRegCreateKey(hDomainKey, 360 szAccountKeyName, 361 KEY_ALL_ACCESS, 362 &hAccountKey); 363 if (!NT_SUCCESS(Status)) 364 return Status; 365 366 Status = SampRegSetValue(hAccountKey, 367 L"F", 368 REG_BINARY, 369 (LPVOID)&FixedUserData, 370 sizeof(SAM_USER_FIXED_DATA)); 371 if (!NT_SUCCESS(Status)) 372 goto done; 373 374 Status = SampRegSetValue(hAccountKey, 375 L"Name", 376 REG_SZ, 377 (LPVOID)lpAccountName, 378 (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); 379 if (!NT_SUCCESS(Status)) 380 goto done; 381 382 Status = SampRegSetValue(hAccountKey, 383 L"FullName", 384 REG_SZ, 385 (LPVOID)lpEmptyString, 386 sizeof(WCHAR)); 387 if (!NT_SUCCESS(Status)) 388 goto done; 389 390 Status = SampRegSetValue(hAccountKey, 391 L"HomeDirectory", 392 REG_SZ, 393 (LPVOID)lpEmptyString, 394 sizeof(WCHAR)); 395 if (!NT_SUCCESS(Status)) 396 goto done; 397 398 Status = SampRegSetValue(hAccountKey, 399 L"HomeDirectoryDrive", 400 REG_SZ, 401 (LPVOID)lpEmptyString, 402 sizeof(WCHAR)); 403 if (!NT_SUCCESS(Status)) 404 goto done; 405 406 Status = SampRegSetValue(hAccountKey, 407 L"ScriptPath", 408 REG_SZ, 409 (LPVOID)lpEmptyString, 410 sizeof(WCHAR)); 411 if (!NT_SUCCESS(Status)) 412 goto done; 413 414 Status = SampRegSetValue(hAccountKey, 415 L"ProfilePath", 416 REG_SZ, 417 (LPVOID)lpEmptyString, 418 sizeof(WCHAR)); 419 if (!NT_SUCCESS(Status)) 420 goto done; 421 422 Status = SampRegSetValue(hAccountKey, 423 L"AdminComment", 424 REG_SZ, 425 (LPVOID)lpComment, 426 (wcslen(lpComment) + 1) * sizeof(WCHAR)); 427 if (!NT_SUCCESS(Status)) 428 goto done; 429 430 Status = SampRegSetValue(hAccountKey, 431 L"UserComment", 432 REG_SZ, 433 (LPVOID)lpEmptyString, 434 sizeof(WCHAR)); 435 if (!NT_SUCCESS(Status)) 436 goto done; 437 438 Status = SampRegSetValue(hAccountKey, 439 L"WorkStations", 440 REG_SZ, 441 (LPVOID)lpEmptyString, 442 sizeof(WCHAR)); 443 if (!NT_SUCCESS(Status)) 444 goto done; 445 446 Status = SampRegSetValue(hAccountKey, 447 L"Parameters", 448 REG_SZ, 449 (LPVOID)lpEmptyString, 450 sizeof(WCHAR)); 451 if (!NT_SUCCESS(Status)) 452 goto done; 453 454 /* Set LogonHours attribute*/ 455 *((PUSHORT)LogonHours) = 168; 456 memset(&(LogonHours[2]), 0xff, 21); 457 458 Status = SampRegSetValue(hAccountKey, 459 L"LogonHours", 460 REG_BINARY, 461 (LPVOID)LogonHours, 462 sizeof(LogonHours)); 463 if (!NT_SUCCESS(Status)) 464 goto done; 465 466 /* Set Groups attribute*/ 467 GroupMembership.RelativeId = DOMAIN_GROUP_RID_USERS; 468 GroupMembership.Attributes = SE_GROUP_MANDATORY | 469 SE_GROUP_ENABLED | 470 SE_GROUP_ENABLED_BY_DEFAULT; 471 472 Status = SampRegSetValue(hAccountKey, 473 L"Groups", 474 REG_BINARY, 475 (LPVOID)&GroupMembership, 476 sizeof(GROUP_MEMBERSHIP)); 477 if (!NT_SUCCESS(Status)) 478 goto done; 479 480 /* Set LMPwd attribute*/ 481 Status = SampRegSetValue(hAccountKey, 482 L"LMPwd", 483 REG_BINARY, 484 (LPVOID)&EmptyLmHash, 485 sizeof(ENCRYPTED_LM_OWF_PASSWORD)); 486 if (!NT_SUCCESS(Status)) 487 goto done; 488 489 /* Set NTPwd attribute*/ 490 Status = SampRegSetValue(hAccountKey, 491 L"NTPwd", 492 REG_BINARY, 493 (LPVOID)&EmptyNtHash, 494 sizeof(ENCRYPTED_NT_OWF_PASSWORD)); 495 if (!NT_SUCCESS(Status)) 496 goto done; 497 498 /* Set LMPwdHistory attribute*/ 499 Status = SampRegSetValue(hAccountKey, 500 L"LMPwdHistory", 501 REG_BINARY, 502 NULL, 503 0); 504 if (!NT_SUCCESS(Status)) 505 goto done; 506 507 /* Set NTPwdHistory attribute*/ 508 Status = SampRegSetValue(hAccountKey, 509 L"NTPwdHistory", 510 REG_BINARY, 511 NULL, 512 0); 513 if (!NT_SUCCESS(Status)) 514 goto done; 515 516 /* FIXME: Set SecDesc attribute*/ 517 518 519 Status = SampRegOpenKey(hDomainKey, 520 L"Users\\Names", 521 KEY_ALL_ACCESS, 522 &hNamesKey); 523 if (!NT_SUCCESS(Status)) 524 goto done; 525 526 Status = SampRegSetValue(hNamesKey, 527 lpAccountName, 528 REG_DWORD, 529 (LPVOID)&ulRelativeId, 530 sizeof(ULONG)); 531 532 done: 533 if (hNamesKey != NULL) 534 SampRegCloseKey(hNamesKey); 535 536 if (hAccountKey != NULL) 537 { 538 SampRegCloseKey(hAccountKey); 539 540 if (!NT_SUCCESS(Status)) 541 SampRegDeleteKey(hDomainKey, 542 szAccountKeyName); 543 } 544 545 return Status; 546 } 547 548 549 static 550 NTSTATUS 551 SampSetupCreateDomain(IN HANDLE hServerKey, 552 IN LPCWSTR lpKeyName, 553 IN LPCWSTR lpDomainName, 554 IN PSID lpDomainSid, 555 IN BOOLEAN bBuiltinDomain, 556 OUT HANDLE *lpDomainKey) 557 { 558 SAM_DOMAIN_FIXED_DATA FixedData; 559 WCHAR szDomainKeyName[32]; 560 LPWSTR lpEmptyString = L""; 561 HANDLE hDomainKey = NULL; 562 HANDLE hAliasesKey = NULL; 563 HANDLE hGroupsKey = NULL; 564 HANDLE hUsersKey = NULL; 565 HANDLE hNamesKey = NULL; 566 PSECURITY_DESCRIPTOR Sd = NULL; 567 ULONG SdSize = 0; 568 NTSTATUS Status; 569 570 if (lpDomainKey != NULL) 571 *lpDomainKey = NULL; 572 573 /* Initialize the fixed domain data */ 574 memset(&FixedData, 0, sizeof(SAM_DOMAIN_FIXED_DATA)); 575 FixedData.Version = 1; 576 NtQuerySystemTime(&FixedData.CreationTime); 577 FixedData.DomainModifiedCount.QuadPart = 0; 578 FixedData.MaxPasswordAge.QuadPart = -(6LL * 7LL * 24LL * 60LL * 60LL * TICKS_PER_SECOND); /* 6 weeks */ 579 FixedData.MinPasswordAge.QuadPart = 0; /* right now */ 580 FixedData.ForceLogoff.QuadPart = LLONG_MAX; /* very far in the future aka never */ 581 FixedData.LockoutDuration.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND); /* 30 minutes */ 582 FixedData.LockoutObservationWindow.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND); /* 30 minutes */ 583 FixedData.ModifiedCountAtLastPromotion.QuadPart = 0; 584 FixedData.NextRid = 1000; 585 FixedData.PasswordProperties = 0; 586 FixedData.MinPasswordLength = 0; 587 FixedData.PasswordHistoryLength = 0; 588 FixedData.LockoutThreshold = 0; 589 FixedData.DomainServerState = DomainServerEnabled; 590 FixedData.DomainServerRole = DomainServerRolePrimary; 591 FixedData.UasCompatibilityRequired = TRUE; 592 593 wcscpy(szDomainKeyName, L"Domains\\"); 594 wcscat(szDomainKeyName, lpKeyName); 595 596 Status = SampRegCreateKey(hServerKey, 597 szDomainKeyName, 598 KEY_ALL_ACCESS, 599 &hDomainKey); 600 if (!NT_SUCCESS(Status)) 601 return Status; 602 603 /* Set the fixed data value */ 604 Status = SampRegSetValue(hDomainKey, 605 L"F", 606 REG_BINARY, 607 (LPVOID)&FixedData, 608 sizeof(SAM_DOMAIN_FIXED_DATA)); 609 if (!NT_SUCCESS(Status)) 610 goto done; 611 612 if (lpDomainSid != NULL) 613 { 614 Status = SampRegSetValue(hDomainKey, 615 L"Name", 616 REG_SZ, 617 (LPVOID)lpDomainName, 618 (wcslen(lpDomainName) + 1) * sizeof(WCHAR)); 619 if (!NT_SUCCESS(Status)) 620 goto done; 621 622 Status = SampRegSetValue(hDomainKey, 623 L"SID", 624 REG_BINARY, 625 (LPVOID)lpDomainSid, 626 RtlLengthSid(lpDomainSid)); 627 if (!NT_SUCCESS(Status)) 628 goto done; 629 } 630 631 Status = SampRegSetValue(hDomainKey, 632 L"OemInformation", 633 REG_SZ, 634 (LPVOID)lpEmptyString, 635 sizeof(WCHAR)); 636 if (!NT_SUCCESS(Status)) 637 goto done; 638 639 Status = SampRegSetValue(hDomainKey, 640 L"ReplicaSourceNodeName", 641 REG_SZ, 642 (LPVOID)lpEmptyString, 643 sizeof(WCHAR)); 644 if (!NT_SUCCESS(Status)) 645 goto done; 646 647 /* Create the Alias container */ 648 Status = SampRegCreateKey(hDomainKey, 649 L"Aliases", 650 KEY_ALL_ACCESS, 651 &hAliasesKey); 652 if (!NT_SUCCESS(Status)) 653 goto done; 654 655 Status = SampRegCreateKey(hAliasesKey, 656 L"Names", 657 KEY_ALL_ACCESS, 658 &hNamesKey); 659 if (!NT_SUCCESS(Status)) 660 goto done; 661 662 SampRegCloseKey(hNamesKey); 663 664 /* Create the Groups container */ 665 Status = SampRegCreateKey(hDomainKey, 666 L"Groups", 667 KEY_ALL_ACCESS, 668 &hGroupsKey); 669 if (!NT_SUCCESS(Status)) 670 goto done; 671 672 Status = SampRegCreateKey(hGroupsKey, 673 L"Names", 674 KEY_ALL_ACCESS, 675 &hNamesKey); 676 if (!NT_SUCCESS(Status)) 677 goto done; 678 679 SampRegCloseKey(hNamesKey); 680 681 /* Create the Users container */ 682 Status = SampRegCreateKey(hDomainKey, 683 L"Users", 684 KEY_ALL_ACCESS, 685 &hUsersKey); 686 if (!NT_SUCCESS(Status)) 687 goto done; 688 689 Status = SampRegCreateKey(hUsersKey, 690 L"Names", 691 KEY_ALL_ACCESS, 692 &hNamesKey); 693 if (!NT_SUCCESS(Status)) 694 goto done; 695 696 /* Create the server SD */ 697 if (bBuiltinDomain == TRUE) 698 Status = SampCreateBuiltinDomainSD(&Sd, 699 &SdSize); 700 else 701 Status = SampCreateAccountDomainSD(&Sd, 702 &SdSize); 703 704 if (!NT_SUCCESS(Status)) 705 goto done; 706 707 /* Set SecDesc attribute*/ 708 Status = SampRegSetValue(hServerKey, 709 L"SecDesc", 710 REG_BINARY, 711 Sd, 712 SdSize); 713 if (!NT_SUCCESS(Status)) 714 goto done; 715 716 SampRegCloseKey(hNamesKey); 717 718 if (lpDomainKey != NULL) 719 *lpDomainKey = hDomainKey; 720 721 done: 722 if (Sd != NULL) 723 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); 724 725 if (hAliasesKey != NULL) 726 SampRegCloseKey(hAliasesKey); 727 728 if (hGroupsKey != NULL) 729 SampRegCloseKey(hGroupsKey); 730 731 if (hUsersKey != NULL) 732 SampRegCloseKey(hUsersKey); 733 734 if (!NT_SUCCESS(Status)) 735 { 736 if (hDomainKey != NULL) 737 SampRegCloseKey(hDomainKey); 738 } 739 740 return Status; 741 } 742 743 744 static 745 NTSTATUS 746 SampSetupCreateServer(IN HANDLE hSamKey, 747 OUT HANDLE *lpServerKey) 748 { 749 HANDLE hServerKey = NULL; 750 HANDLE hDomainsKey = NULL; 751 PSECURITY_DESCRIPTOR Sd = NULL; 752 ULONG SdSize = 0; 753 NTSTATUS Status; 754 755 Status = SampRegCreateKey(hSamKey, 756 L"SAM", 757 KEY_ALL_ACCESS, 758 &hServerKey); 759 if (!NT_SUCCESS(Status)) 760 return Status; 761 762 Status = SampRegCreateKey(hServerKey, 763 L"Domains", 764 KEY_ALL_ACCESS, 765 &hDomainsKey); 766 if (!NT_SUCCESS(Status)) 767 goto done; 768 769 /* Create the server SD */ 770 Status = SampCreateServerSD(&Sd, 771 &SdSize); 772 if (!NT_SUCCESS(Status)) 773 goto done; 774 775 /* Set SecDesc attribute*/ 776 Status = SampRegSetValue(hServerKey, 777 L"SecDesc", 778 REG_BINARY, 779 Sd, 780 SdSize); 781 if (!NT_SUCCESS(Status)) 782 goto done; 783 784 SampRegCloseKey(hDomainsKey); 785 786 *lpServerKey = hServerKey; 787 788 done: 789 if (Sd != NULL) 790 RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); 791 792 return Status; 793 } 794 795 796 NTSTATUS 797 SampGetAccountDomainInfo(PPOLICY_ACCOUNT_DOMAIN_INFO *AccountDomainInfo) 798 { 799 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 800 LSA_HANDLE PolicyHandle; 801 NTSTATUS Status; 802 803 TRACE("SampGetAccountDomainInfo\n"); 804 805 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); 806 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); 807 808 Status = LsaOpenPolicy(NULL, 809 &ObjectAttributes, 810 POLICY_VIEW_LOCAL_INFORMATION, 811 &PolicyHandle); 812 if (Status != STATUS_SUCCESS) 813 { 814 ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status); 815 return Status; 816 } 817 818 Status = LsaQueryInformationPolicy(PolicyHandle, 819 PolicyAccountDomainInformation, 820 (PVOID *)AccountDomainInfo); 821 822 LsaClose(PolicyHandle); 823 824 return Status; 825 } 826 827 828 BOOL 829 SampInitializeSAM(VOID) 830 { 831 PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL; 832 HANDLE hSamKey = NULL; 833 HANDLE hServerKey = NULL; 834 HANDLE hBuiltinDomainKey = NULL; 835 HANDLE hAccountDomainKey = NULL; 836 PSID pBuiltinSid = NULL; 837 BOOL bResult = TRUE; 838 PSID pSid; 839 HINSTANCE hInstance; 840 WCHAR szComment[256]; 841 WCHAR szName[80]; 842 NTSTATUS Status; 843 844 TRACE("SampInitializeSAM() called\n"); 845 846 hInstance = GetModuleHandleW(L"samsrv.dll"); 847 848 /* Open the SAM key */ 849 Status = SampRegOpenKey(NULL, 850 L"\\Registry\\Machine\\SAM", 851 KEY_READ | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, 852 &hSamKey); 853 if (!NT_SUCCESS(Status)) 854 { 855 ERR("Failed to open the SAM key (Status: 0x%08lx)\n", Status); 856 return FALSE; 857 } 858 859 /* Create the SAM Server object */ 860 Status = SampSetupCreateServer(hSamKey, 861 &hServerKey); 862 if (!NT_SUCCESS(Status)) 863 { 864 bResult = FALSE; 865 goto done; 866 } 867 868 /* Create and initialize the Builtin Domain SID */ 869 pBuiltinSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1)); 870 if (pBuiltinSid == NULL) 871 { 872 ERR("Failed to alloacte the Builtin Domain SID\n"); 873 bResult = FALSE; 874 goto done; 875 } 876 877 RtlInitializeSid(pBuiltinSid, &SecurityNtAuthority, 1); 878 *(RtlSubAuthoritySid(pBuiltinSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID; 879 880 /* Get account domain information */ 881 Status = SampGetAccountDomainInfo(&AccountDomainInfo); 882 if (!NT_SUCCESS(Status)) 883 { 884 ERR("SampGetAccountDomainInfo failed (Status %08lx)\n", Status); 885 bResult = FALSE; 886 goto done; 887 } 888 889 SampLoadString(hInstance, IDS_DOMAIN_BUILTIN_NAME, szName, 80); 890 891 /* Create the Builtin domain */ 892 Status = SampSetupCreateDomain(hServerKey, 893 L"Builtin", 894 szName, 895 pBuiltinSid, 896 TRUE, 897 &hBuiltinDomainKey); 898 if (!NT_SUCCESS(Status)) 899 { 900 bResult = FALSE; 901 goto done; 902 } 903 904 SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_NAME, szName, 80); 905 SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_COMMENT, szComment, 256); 906 907 SampSetupCreateAliasAccount(hBuiltinDomainKey, 908 szName, 909 szComment, 910 DOMAIN_ALIAS_RID_ADMINS); 911 912 SampLoadString(hInstance, IDS_ALIAS_USERS_NAME, szName, 80); 913 SampLoadString(hInstance, IDS_ALIAS_USERS_COMMENT, szComment, 256); 914 915 SampSetupCreateAliasAccount(hBuiltinDomainKey, 916 szName, 917 szComment, 918 DOMAIN_ALIAS_RID_USERS); 919 920 SampLoadString(hInstance, IDS_ALIAS_GUESTS_NAME, szName, 80); 921 SampLoadString(hInstance, IDS_ALIAS_GUESTS_COMMENT, szComment, 256); 922 923 SampSetupCreateAliasAccount(hBuiltinDomainKey, 924 szName, 925 szComment, 926 DOMAIN_ALIAS_RID_GUESTS); 927 928 SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_NAME, szName, 80); 929 SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_COMMENT, szComment, 256); 930 931 SampSetupCreateAliasAccount(hBuiltinDomainKey, 932 szName, 933 szComment, 934 DOMAIN_ALIAS_RID_POWER_USERS); 935 936 /* Add the Administrator user to the Administrators alias */ 937 pSid = AppendRidToSid(AccountDomainInfo->DomainSid, 938 DOMAIN_USER_RID_ADMIN); 939 if (pSid != NULL) 940 { 941 SampSetupAddMemberToAlias(hBuiltinDomainKey, 942 DOMAIN_ALIAS_RID_ADMINS, 943 pSid); 944 945 RtlFreeHeap(RtlGetProcessHeap(), 0, pSid); 946 } 947 948 /* Add the Guest user to the Guests alias */ 949 pSid = AppendRidToSid(AccountDomainInfo->DomainSid, 950 DOMAIN_USER_RID_GUEST); 951 if (pSid != NULL) 952 { 953 SampSetupAddMemberToAlias(hBuiltinDomainKey, 954 DOMAIN_ALIAS_RID_GUESTS, 955 pSid); 956 957 RtlFreeHeap(RtlGetProcessHeap(), 0, pSid); 958 } 959 960 961 /* Create the Account domain */ 962 Status = SampSetupCreateDomain(hServerKey, 963 L"Account", 964 L"", 965 AccountDomainInfo->DomainSid, 966 FALSE, 967 &hAccountDomainKey); 968 if (!NT_SUCCESS(Status)) 969 { 970 bResult = FALSE; 971 goto done; 972 } 973 974 SampLoadString(hInstance, IDS_GROUP_NONE_NAME, szName, 80); 975 SampLoadString(hInstance, IDS_GROUP_NONE_COMMENT, szComment, 256); 976 977 SampSetupCreateGroupAccount(hAccountDomainKey, 978 szName, 979 szComment, 980 DOMAIN_GROUP_RID_USERS); 981 982 SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_NAME, szName, 80); 983 SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_COMMENT, szComment, 256); 984 985 SampSetupCreateUserAccount(hAccountDomainKey, 986 szName, 987 szComment, 988 DOMAIN_USER_RID_ADMIN, 989 USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT); 990 991 SampSetupAddMemberToGroup(hAccountDomainKey, 992 DOMAIN_GROUP_RID_USERS, 993 DOMAIN_USER_RID_ADMIN); 994 995 SampLoadString(hInstance, IDS_USER_GUEST_NAME, szName, 80); 996 SampLoadString(hInstance, IDS_USER_GUEST_COMMENT, szComment, 256); 997 998 SampSetupCreateUserAccount(hAccountDomainKey, 999 szName, 1000 szComment, 1001 DOMAIN_USER_RID_GUEST, 1002 USER_ACCOUNT_DISABLED | USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT); 1003 1004 SampSetupAddMemberToGroup(hAccountDomainKey, 1005 DOMAIN_GROUP_RID_USERS, 1006 DOMAIN_USER_RID_GUEST); 1007 1008 done: 1009 if (AccountDomainInfo) 1010 LsaFreeMemory(AccountDomainInfo); 1011 1012 if (pBuiltinSid) 1013 RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid); 1014 1015 if (hAccountDomainKey != NULL) 1016 SampRegCloseKey(hAccountDomainKey); 1017 1018 if (hBuiltinDomainKey != NULL) 1019 SampRegCloseKey(hBuiltinDomainKey); 1020 1021 if (hServerKey != NULL) 1022 SampRegCloseKey(hServerKey); 1023 1024 if (hSamKey != NULL) 1025 SampRegCloseKey(hSamKey); 1026 1027 TRACE("SampInitializeSAM() done\n"); 1028 1029 return bResult; 1030 } 1031