1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * PURPOSE: System setup 5 * FILE: dll/win32/syssetup/security.c 6 * PROGRAMER: Eric Kohl 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include "precomp.h" 12 13 #include <ntlsa.h> 14 #include <ntsecapi.h> 15 #include <ntsam.h> 16 #include <sddl.h> 17 18 #define NDEBUG 19 #include <debug.h> 20 21 /* FUNCTIONS ****************************************************************/ 22 23 NTSTATUS 24 WINAPI 25 SetAccountsDomainSid( 26 PSID DomainSid, 27 LPCWSTR DomainName) 28 { 29 PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL; 30 POLICY_ACCOUNT_DOMAIN_INFO Info; 31 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 32 LSA_HANDLE PolicyHandle; 33 34 SAM_HANDLE ServerHandle = NULL; 35 SAM_HANDLE DomainHandle = NULL; 36 DOMAIN_NAME_INFORMATION DomainNameInfo; 37 38 NTSTATUS Status; 39 40 DPRINT("SYSSETUP: SetAccountsDomainSid\n"); 41 42 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); 43 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); 44 45 Status = LsaOpenPolicy(NULL, 46 &ObjectAttributes, 47 POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, 48 &PolicyHandle); 49 if (Status != STATUS_SUCCESS) 50 { 51 DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status); 52 return Status; 53 } 54 55 Status = LsaQueryInformationPolicy(PolicyHandle, 56 PolicyAccountDomainInformation, 57 (PVOID *)&OrigInfo); 58 if (Status == STATUS_SUCCESS && OrigInfo != NULL) 59 { 60 if (DomainName == NULL) 61 { 62 Info.DomainName.Buffer = OrigInfo->DomainName.Buffer; 63 Info.DomainName.Length = OrigInfo->DomainName.Length; 64 Info.DomainName.MaximumLength = OrigInfo->DomainName.MaximumLength; 65 } 66 else 67 { 68 Info.DomainName.Buffer = (LPWSTR)DomainName; 69 Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); 70 Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR); 71 } 72 73 if (DomainSid == NULL) 74 Info.DomainSid = OrigInfo->DomainSid; 75 else 76 Info.DomainSid = DomainSid; 77 } 78 else 79 { 80 Info.DomainName.Buffer = (LPWSTR)DomainName; 81 Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); 82 Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR); 83 Info.DomainSid = DomainSid; 84 } 85 86 Status = LsaSetInformationPolicy(PolicyHandle, 87 PolicyAccountDomainInformation, 88 (PVOID)&Info); 89 if (Status != STATUS_SUCCESS) 90 { 91 DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status); 92 } 93 94 if (OrigInfo != NULL) 95 LsaFreeMemory(OrigInfo); 96 97 LsaClose(PolicyHandle); 98 99 DomainNameInfo.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); 100 DomainNameInfo.DomainName.MaximumLength = (wcslen(DomainName) + 1) * sizeof(WCHAR); 101 DomainNameInfo.DomainName.Buffer = (LPWSTR)DomainName; 102 103 Status = SamConnect(NULL, 104 &ServerHandle, 105 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 106 NULL); 107 if (NT_SUCCESS(Status)) 108 { 109 Status = SamOpenDomain(ServerHandle, 110 DOMAIN_WRITE_OTHER_PARAMETERS, 111 Info.DomainSid, 112 &DomainHandle); 113 if (NT_SUCCESS(Status)) 114 { 115 Status = SamSetInformationDomain(DomainHandle, 116 DomainNameInformation, 117 (PVOID)&DomainNameInfo); 118 if (!NT_SUCCESS(Status)) 119 { 120 DPRINT1("SamSetInformationDomain failed (Status: 0x%08lx)\n", Status); 121 } 122 123 SamCloseHandle(DomainHandle); 124 } 125 else 126 { 127 DPRINT1("SamOpenDomain failed (Status: 0x%08lx)\n", Status); 128 } 129 130 SamCloseHandle(ServerHandle); 131 } 132 133 return Status; 134 } 135 136 137 /* Hack */ 138 static 139 NTSTATUS 140 SetPrimaryDomain(LPCWSTR DomainName, 141 PSID DomainSid) 142 { 143 PPOLICY_PRIMARY_DOMAIN_INFO OrigInfo = NULL; 144 POLICY_PRIMARY_DOMAIN_INFO Info; 145 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 146 LSA_HANDLE PolicyHandle; 147 NTSTATUS Status; 148 149 DPRINT1("SYSSETUP: SetPrimaryDomain()\n"); 150 151 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); 152 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); 153 154 Status = LsaOpenPolicy(NULL, 155 &ObjectAttributes, 156 POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, 157 &PolicyHandle); 158 if (Status != STATUS_SUCCESS) 159 { 160 DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status); 161 return Status; 162 } 163 164 Status = LsaQueryInformationPolicy(PolicyHandle, 165 PolicyPrimaryDomainInformation, 166 (PVOID *)&OrigInfo); 167 if (Status == STATUS_SUCCESS && OrigInfo != NULL) 168 { 169 if (DomainName == NULL) 170 { 171 Info.Name.Buffer = OrigInfo->Name.Buffer; 172 Info.Name.Length = OrigInfo->Name.Length; 173 Info.Name.MaximumLength = OrigInfo->Name.MaximumLength; 174 } 175 else 176 { 177 Info.Name.Buffer = (LPWSTR)DomainName; 178 Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR); 179 Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR); 180 } 181 182 if (DomainSid == NULL) 183 Info.Sid = OrigInfo->Sid; 184 else 185 Info.Sid = DomainSid; 186 } 187 else 188 { 189 Info.Name.Buffer = (LPWSTR)DomainName; 190 Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR); 191 Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR); 192 Info.Sid = DomainSid; 193 } 194 195 Status = LsaSetInformationPolicy(PolicyHandle, 196 PolicyPrimaryDomainInformation, 197 (PVOID)&Info); 198 if (Status != STATUS_SUCCESS) 199 { 200 DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status); 201 } 202 203 if (OrigInfo != NULL) 204 LsaFreeMemory(OrigInfo); 205 206 LsaClose(PolicyHandle); 207 208 return Status; 209 } 210 211 212 static 213 VOID 214 InstallBuiltinAccounts(VOID) 215 { 216 LPWSTR BuiltinAccounts[] = { 217 L"S-1-1-0", /* Everyone */ 218 L"S-1-5-4", /* Interactive */ 219 L"S-1-5-6", /* Service */ 220 L"S-1-5-19", /* Local Service */ 221 L"S-1-5-20", /* Network Service */ 222 L"S-1-5-32-544", /* Administrators */ 223 L"S-1-5-32-545", /* Users */ 224 L"S-1-5-32-547", /* Power Users */ 225 L"S-1-5-32-551", /* Backup Operators */ 226 L"S-1-5-32-555"}; /* Remote Desktop Users */ 227 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 228 NTSTATUS Status; 229 LSA_HANDLE PolicyHandle = NULL; 230 LSA_HANDLE AccountHandle = NULL; 231 PSID AccountSid; 232 ULONG i; 233 234 DPRINT("InstallBuiltinAccounts()\n"); 235 236 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); 237 238 Status = LsaOpenPolicy(NULL, 239 &ObjectAttributes, 240 POLICY_CREATE_ACCOUNT, 241 &PolicyHandle); 242 if (!NT_SUCCESS(Status)) 243 { 244 DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status); 245 return; 246 } 247 248 for (i = 0; i < 10; i++) 249 { 250 if (!ConvertStringSidToSid(BuiltinAccounts[i], &AccountSid)) 251 { 252 DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", BuiltinAccounts[i], GetLastError()); 253 continue; 254 } 255 256 Status = LsaCreateAccount(PolicyHandle, 257 AccountSid, 258 0, 259 &AccountHandle); 260 if (NT_SUCCESS(Status)) 261 { 262 LsaClose(AccountHandle); 263 } 264 265 LocalFree(AccountSid); 266 } 267 268 LsaClose(PolicyHandle); 269 } 270 271 272 static 273 VOID 274 InstallPrivileges(VOID) 275 { 276 HINF hSecurityInf = INVALID_HANDLE_VALUE; 277 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 278 WCHAR szPrivilegeString[256]; 279 WCHAR szSidString[256]; 280 INFCONTEXT InfContext; 281 DWORD i; 282 PSID AccountSid = NULL; 283 NTSTATUS Status; 284 LSA_HANDLE PolicyHandle = NULL; 285 LSA_UNICODE_STRING RightString; 286 PLSA_TRANSLATED_SID2 Sids = NULL; 287 288 DPRINT("InstallPrivileges()\n"); 289 290 hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer, 291 NULL, 292 INF_STYLE_WIN4, 293 NULL); 294 if (hSecurityInf == INVALID_HANDLE_VALUE) 295 { 296 DPRINT1("SetupOpenInfFileW failed\n"); 297 return; 298 } 299 300 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); 301 302 Status = LsaOpenPolicy(NULL, 303 &ObjectAttributes, 304 POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, 305 &PolicyHandle); 306 if (!NT_SUCCESS(Status)) 307 { 308 DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status); 309 goto done; 310 } 311 312 if (!SetupFindFirstLineW(hSecurityInf, 313 L"Privilege Rights", 314 NULL, 315 &InfContext)) 316 { 317 DPRINT1("SetupFindfirstLineW failed\n"); 318 goto done; 319 } 320 321 do 322 { 323 /* Retrieve the privilege name */ 324 if (!SetupGetStringFieldW(&InfContext, 325 0, 326 szPrivilegeString, 327 256, 328 NULL)) 329 { 330 DPRINT1("SetupGetStringFieldW() failed\n"); 331 goto done; 332 } 333 DPRINT("Privilege: %S\n", szPrivilegeString); 334 335 for (i = 0; i < SetupGetFieldCount(&InfContext); i++) 336 { 337 if (!SetupGetStringFieldW(&InfContext, 338 i + 1, 339 szSidString, 340 256, 341 NULL)) 342 { 343 DPRINT1("SetupGetStringFieldW() failed\n"); 344 goto done; 345 } 346 DPRINT("SID: %S\n", szSidString); 347 348 if (szSidString[0] == UNICODE_NULL) 349 continue; 350 351 if (szSidString[0] == L'*') 352 { 353 DPRINT("Account Sid: %S\n", &szSidString[1]); 354 355 if (!ConvertStringSidToSid(&szSidString[1], &AccountSid)) 356 { 357 DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", szSidString, GetLastError()); 358 continue; 359 } 360 } 361 else 362 { 363 DPRINT("Account name: %S\n", szSidString); 364 continue; 365 366 } 367 368 RtlInitUnicodeString(&RightString, szPrivilegeString); 369 Status = LsaAddAccountRights(PolicyHandle, 370 (AccountSid != NULL) ? AccountSid : Sids[0].Sid, 371 &RightString, 372 1); 373 if (!NT_SUCCESS(Status)) 374 { 375 DPRINT1("LsaAddAccountRights() failed (Status %08lx)\n", Status); 376 } 377 378 if (Sids != NULL) 379 { 380 LsaFreeMemory(Sids); 381 Sids = NULL; 382 } 383 384 if (AccountSid != NULL) 385 { 386 LocalFree(AccountSid); 387 AccountSid = NULL; 388 } 389 } 390 391 } 392 while (SetupFindNextLine(&InfContext, &InfContext)); 393 394 done: 395 if (PolicyHandle != NULL) 396 LsaClose(PolicyHandle); 397 398 if (hSecurityInf != INVALID_HANDLE_VALUE) 399 SetupCloseInfFile(hSecurityInf); 400 } 401 402 403 VOID 404 InstallSecurity(VOID) 405 { 406 InstallBuiltinAccounts(); 407 InstallPrivileges(); 408 409 /* Hack */ 410 SetPrimaryDomain(L"WORKGROUP", NULL); 411 } 412 413 414 NTSTATUS 415 SetAdministratorPassword(LPCWSTR Password) 416 { 417 PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL; 418 PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL; 419 USER_SET_PASSWORD_INFORMATION PasswordInfo; 420 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 421 LSA_HANDLE PolicyHandle = NULL; 422 SAM_HANDLE ServerHandle = NULL; 423 SAM_HANDLE DomainHandle = NULL; 424 SAM_HANDLE UserHandle = NULL; 425 NTSTATUS Status; 426 427 DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password); 428 429 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); 430 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); 431 432 Status = LsaOpenPolicy(NULL, 433 &ObjectAttributes, 434 POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, 435 &PolicyHandle); 436 if (Status != STATUS_SUCCESS) 437 { 438 DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status); 439 return Status; 440 } 441 442 Status = LsaQueryInformationPolicy(PolicyHandle, 443 PolicyAccountDomainInformation, 444 (PVOID *)&OrigInfo); 445 if (!NT_SUCCESS(Status)) 446 { 447 DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status); 448 goto done; 449 } 450 451 Status = SamConnect(NULL, 452 &ServerHandle, 453 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 454 NULL); 455 if (!NT_SUCCESS(Status)) 456 { 457 DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status); 458 goto done; 459 } 460 461 Status = SamOpenDomain(ServerHandle, 462 DOMAIN_LOOKUP, 463 OrigInfo->DomainSid, 464 &DomainHandle); 465 if (!NT_SUCCESS(Status)) 466 { 467 DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status); 468 goto done; 469 } 470 471 Status = SamOpenUser(DomainHandle, 472 USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL, 473 DOMAIN_USER_RID_ADMIN, 474 &UserHandle); 475 if (!NT_SUCCESS(Status)) 476 { 477 DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status); 478 goto done; 479 } 480 481 RtlInitUnicodeString(&PasswordInfo.Password, Password); 482 PasswordInfo.PasswordExpired = FALSE; 483 484 Status = SamSetInformationUser(UserHandle, 485 UserSetPasswordInformation, 486 (PVOID)&PasswordInfo); 487 if (!NT_SUCCESS(Status)) 488 { 489 DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); 490 goto done; 491 } 492 493 Status = SamQueryInformationUser(UserHandle, 494 UserAccountNameInformation, 495 (PVOID*)&AccountNameInfo); 496 if (!NT_SUCCESS(Status)) 497 { 498 DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); 499 goto done; 500 } 501 502 AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(), 503 HEAP_ZERO_MEMORY, 504 AccountNameInfo->UserName.Length + sizeof(WCHAR)); 505 if (AdminInfo.Name != NULL) 506 RtlCopyMemory(AdminInfo.Name, 507 AccountNameInfo->UserName.Buffer, 508 AccountNameInfo->UserName.Length); 509 510 AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(), 511 HEAP_ZERO_MEMORY, 512 OrigInfo->DomainName.Length + sizeof(WCHAR)); 513 if (AdminInfo.Domain != NULL) 514 RtlCopyMemory(AdminInfo.Domain, 515 OrigInfo->DomainName.Buffer, 516 OrigInfo->DomainName.Length); 517 518 AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(), 519 0, 520 (wcslen(Password) + 1) * sizeof(WCHAR)); 521 if (AdminInfo.Password != NULL) 522 wcscpy(AdminInfo.Password, Password); 523 524 DPRINT("Administrator Name: %S\n", AdminInfo.Name); 525 DPRINT("Administrator Domain: %S\n", AdminInfo.Domain); 526 DPRINT("Administrator Password: %S\n", AdminInfo.Password); 527 528 done: 529 if (AccountNameInfo != NULL) 530 SamFreeMemory(AccountNameInfo); 531 532 if (OrigInfo != NULL) 533 LsaFreeMemory(OrigInfo); 534 535 if (PolicyHandle != NULL) 536 LsaClose(PolicyHandle); 537 538 if (UserHandle != NULL) 539 SamCloseHandle(UserHandle); 540 541 if (DomainHandle != NULL) 542 SamCloseHandle(DomainHandle); 543 544 if (ServerHandle != NULL) 545 SamCloseHandle(ServerHandle); 546 547 DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status); 548 549 return Status; 550 } 551 552 553 VOID 554 SetAutoAdminLogon(VOID) 555 { 556 WCHAR szAutoAdminLogon[2]; 557 HKEY hKey = NULL; 558 DWORD dwType; 559 DWORD dwSize; 560 LONG lError; 561 562 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 563 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 564 0, 565 KEY_READ | KEY_WRITE, 566 &hKey); 567 if (lError != ERROR_SUCCESS) 568 return; 569 570 dwSize = 2 * sizeof(WCHAR); 571 lError = RegQueryValueExW(hKey, 572 L"AutoAdminLogon", 573 NULL, 574 &dwType, 575 (LPBYTE)szAutoAdminLogon, 576 &dwSize); 577 if (lError != ERROR_SUCCESS) 578 goto done; 579 580 if (wcscmp(szAutoAdminLogon, L"1") == 0) 581 { 582 RegSetValueExW(hKey, 583 L"DefaultDomain", 584 0, 585 REG_SZ, 586 (LPBYTE)AdminInfo.Domain, 587 (wcslen(AdminInfo.Domain) + 1) * sizeof(WCHAR)); 588 589 RegSetValueExW(hKey, 590 L"DefaultUserName", 591 0, 592 REG_SZ, 593 (LPBYTE)AdminInfo.Name, 594 (wcslen(AdminInfo.Name) + 1) * sizeof(WCHAR)); 595 596 RegSetValueExW(hKey, 597 L"DefaultPassword", 598 0, 599 REG_SZ, 600 (LPBYTE)AdminInfo.Password, 601 (wcslen(AdminInfo.Password) + 1) * sizeof(WCHAR)); 602 } 603 604 done: 605 if (hKey != NULL) 606 RegCloseKey(hKey); 607 } 608 609 610 /* EOF */ 611 612