1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: lib/advapi32/misc/logon.c 5 * PURPOSE: Logon functions 6 * PROGRAMMER: Eric Kohl 7 */ 8 9 #include <advapi32.h> 10 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 11 12 /* GLOBALS *****************************************************************/ 13 14 HANDLE LsaHandle = NULL; 15 ULONG AuthenticationPackage = 0; 16 17 /* FUNCTIONS ***************************************************************/ 18 19 static 20 NTSTATUS 21 OpenLogonLsaHandle(VOID) 22 { 23 LSA_STRING LogonProcessName; 24 LSA_STRING PackageName; 25 LSA_OPERATIONAL_MODE SecurityMode = 0; 26 NTSTATUS Status; 27 28 RtlInitAnsiString((PANSI_STRING)&LogonProcessName, 29 "User32LogonProcess"); 30 31 Status = LsaRegisterLogonProcess(&LogonProcessName, 32 &LsaHandle, 33 &SecurityMode); 34 if (!NT_SUCCESS(Status)) 35 { 36 TRACE("LsaRegisterLogonProcess failed (Status 0x%08lx)\n", Status); 37 goto done; 38 } 39 40 RtlInitAnsiString((PANSI_STRING)&PackageName, 41 MSV1_0_PACKAGE_NAME); 42 43 Status = LsaLookupAuthenticationPackage(LsaHandle, 44 &PackageName, 45 &AuthenticationPackage); 46 if (!NT_SUCCESS(Status)) 47 { 48 TRACE("LsaLookupAuthenticationPackage failed (Status 0x%08lx)\n", Status); 49 goto done; 50 } 51 52 TRACE("AuthenticationPackage: 0x%08lx\n", AuthenticationPackage); 53 54 done: 55 if (!NT_SUCCESS(Status)) 56 { 57 if (LsaHandle != NULL) 58 { 59 Status = LsaDeregisterLogonProcess(LsaHandle); 60 if (!NT_SUCCESS(Status)) 61 { 62 TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); 63 } 64 } 65 } 66 67 return Status; 68 } 69 70 71 NTSTATUS 72 CloseLogonLsaHandle(VOID) 73 { 74 NTSTATUS Status = STATUS_SUCCESS; 75 76 if (LsaHandle != NULL) 77 { 78 Status = LsaDeregisterLogonProcess(LsaHandle); 79 if (!NT_SUCCESS(Status)) 80 { 81 TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); 82 } 83 } 84 85 return Status; 86 } 87 88 89 /* 90 * @implemented 91 */ 92 BOOL WINAPI 93 CreateProcessAsUserA(HANDLE hToken, 94 LPCSTR lpApplicationName, 95 LPSTR lpCommandLine, 96 LPSECURITY_ATTRIBUTES lpProcessAttributes, 97 LPSECURITY_ATTRIBUTES lpThreadAttributes, 98 BOOL bInheritHandles, 99 DWORD dwCreationFlags, 100 LPVOID lpEnvironment, 101 LPCSTR lpCurrentDirectory, 102 LPSTARTUPINFOA lpStartupInfo, 103 LPPROCESS_INFORMATION lpProcessInformation) 104 { 105 PROCESS_ACCESS_TOKEN AccessToken; 106 NTSTATUS Status; 107 108 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName), 109 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles, 110 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); 111 112 /* Create the process with a suspended main thread */ 113 if (!CreateProcessA(lpApplicationName, 114 lpCommandLine, 115 lpProcessAttributes, 116 lpThreadAttributes, 117 bInheritHandles, 118 dwCreationFlags | CREATE_SUSPENDED, 119 lpEnvironment, 120 lpCurrentDirectory, 121 lpStartupInfo, 122 lpProcessInformation)) 123 { 124 ERR("CreateProcessA failed! GLE: %d\n", GetLastError()); 125 return FALSE; 126 } 127 128 if (hToken != NULL) 129 { 130 AccessToken.Token = hToken; 131 AccessToken.Thread = NULL; 132 133 /* Set the new process token */ 134 Status = NtSetInformationProcess(lpProcessInformation->hProcess, 135 ProcessAccessToken, 136 (PVOID)&AccessToken, 137 sizeof(AccessToken)); 138 if (!NT_SUCCESS (Status)) 139 { 140 ERR("NtSetInformationProcess failed: 0x%08x\n", Status); 141 TerminateProcess(lpProcessInformation->hProcess, Status); 142 SetLastError(RtlNtStatusToDosError(Status)); 143 return FALSE; 144 } 145 } 146 147 /* Resume the main thread */ 148 if (!(dwCreationFlags & CREATE_SUSPENDED)) 149 { 150 ResumeThread(lpProcessInformation->hThread); 151 } 152 153 return TRUE; 154 } 155 156 157 /* 158 * @implemented 159 */ 160 BOOL WINAPI 161 CreateProcessAsUserW(HANDLE hToken, 162 LPCWSTR lpApplicationName, 163 LPWSTR lpCommandLine, 164 LPSECURITY_ATTRIBUTES lpProcessAttributes, 165 LPSECURITY_ATTRIBUTES lpThreadAttributes, 166 BOOL bInheritHandles, 167 DWORD dwCreationFlags, 168 LPVOID lpEnvironment, 169 LPCWSTR lpCurrentDirectory, 170 LPSTARTUPINFOW lpStartupInfo, 171 LPPROCESS_INFORMATION lpProcessInformation) 172 { 173 PROCESS_ACCESS_TOKEN AccessToken; 174 NTSTATUS Status; 175 176 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_w(lpApplicationName), 177 debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles, 178 dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); 179 180 /* Create the process with a suspended main thread */ 181 if (!CreateProcessW(lpApplicationName, 182 lpCommandLine, 183 lpProcessAttributes, 184 lpThreadAttributes, 185 bInheritHandles, 186 dwCreationFlags | CREATE_SUSPENDED, 187 lpEnvironment, 188 lpCurrentDirectory, 189 lpStartupInfo, 190 lpProcessInformation)) 191 { 192 ERR("CreateProcessW failed! GLE: %d\n", GetLastError()); 193 return FALSE; 194 } 195 196 if (hToken != NULL) 197 { 198 AccessToken.Token = hToken; 199 AccessToken.Thread = NULL; 200 201 /* Set the new process token */ 202 Status = NtSetInformationProcess(lpProcessInformation->hProcess, 203 ProcessAccessToken, 204 (PVOID)&AccessToken, 205 sizeof(AccessToken)); 206 if (!NT_SUCCESS (Status)) 207 { 208 ERR("NtSetInformationProcess failed: 0x%08x\n", Status); 209 TerminateProcess(lpProcessInformation->hProcess, Status); 210 SetLastError(RtlNtStatusToDosError(Status)); 211 return FALSE; 212 } 213 } 214 215 /* Resume the main thread */ 216 if (!(dwCreationFlags & CREATE_SUSPENDED)) 217 { 218 ResumeThread(lpProcessInformation->hThread); 219 } 220 221 return TRUE; 222 } 223 224 /* 225 * @implemented 226 */ 227 BOOL WINAPI 228 LogonUserA(LPSTR lpszUsername, 229 LPSTR lpszDomain, 230 LPSTR lpszPassword, 231 DWORD dwLogonType, 232 DWORD dwLogonProvider, 233 PHANDLE phToken) 234 { 235 UNICODE_STRING UserName; 236 UNICODE_STRING Domain; 237 UNICODE_STRING Password; 238 BOOL ret = FALSE; 239 240 UserName.Buffer = NULL; 241 Domain.Buffer = NULL; 242 Password.Buffer = NULL; 243 244 if (!RtlCreateUnicodeStringFromAsciiz(&UserName, lpszUsername)) 245 { 246 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 247 goto UsernameDone; 248 } 249 250 if (!RtlCreateUnicodeStringFromAsciiz(&Domain, lpszDomain)) 251 { 252 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 253 goto DomainDone; 254 } 255 256 if (!RtlCreateUnicodeStringFromAsciiz(&Password, lpszPassword)) 257 { 258 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 259 goto PasswordDone; 260 } 261 262 ret = LogonUserW(UserName.Buffer, 263 Domain.Buffer, 264 Password.Buffer, 265 dwLogonType, 266 dwLogonProvider, 267 phToken); 268 269 if (Password.Buffer != NULL) 270 RtlFreeUnicodeString(&Password); 271 272 PasswordDone: 273 if (Domain.Buffer != NULL) 274 RtlFreeUnicodeString(&Domain); 275 276 DomainDone: 277 if (UserName.Buffer != NULL) 278 RtlFreeUnicodeString(&UserName); 279 280 UsernameDone: 281 return ret; 282 } 283 284 285 /* 286 * @implemented 287 */ 288 BOOL WINAPI 289 LogonUserW(LPWSTR lpszUsername, 290 LPWSTR lpszDomain, 291 LPWSTR lpszPassword, 292 DWORD dwLogonType, 293 DWORD dwLogonProvider, 294 PHANDLE phToken) 295 { 296 SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; 297 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; 298 PSID LogonSid = NULL; 299 PSID LocalSid = NULL; 300 LSA_STRING OriginName; 301 UNICODE_STRING DomainName; 302 UNICODE_STRING UserName; 303 UNICODE_STRING Password; 304 PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL; 305 ULONG AuthInfoLength; 306 ULONG_PTR Ptr; 307 TOKEN_SOURCE TokenSource; 308 PTOKEN_GROUPS TokenGroups = NULL; 309 PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL; 310 ULONG ProfileBufferLength = 0; 311 LUID Luid = {0, 0}; 312 LUID LogonId = {0, 0}; 313 HANDLE TokenHandle = NULL; 314 QUOTA_LIMITS QuotaLimits; 315 SECURITY_LOGON_TYPE LogonType; 316 NTSTATUS SubStatus = STATUS_SUCCESS; 317 NTSTATUS Status; 318 319 *phToken = NULL; 320 321 switch (dwLogonType) 322 { 323 case LOGON32_LOGON_INTERACTIVE: 324 LogonType = Interactive; 325 break; 326 327 case LOGON32_LOGON_NETWORK: 328 LogonType = Network; 329 break; 330 331 case LOGON32_LOGON_BATCH: 332 LogonType = Batch; 333 break; 334 335 case LOGON32_LOGON_SERVICE: 336 LogonType = Service; 337 break; 338 339 default: 340 ERR("Invalid logon type: %ul\n", dwLogonType); 341 Status = STATUS_INVALID_PARAMETER; 342 goto done; 343 } 344 345 if (LsaHandle == NULL) 346 { 347 Status = OpenLogonLsaHandle(); 348 if (!NT_SUCCESS(Status)) 349 goto done; 350 } 351 352 RtlInitAnsiString((PANSI_STRING)&OriginName, 353 "Advapi32 Logon"); 354 355 RtlInitUnicodeString(&DomainName, 356 lpszDomain); 357 358 RtlInitUnicodeString(&UserName, 359 lpszUsername); 360 361 RtlInitUnicodeString(&Password, 362 lpszPassword); 363 364 AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+ 365 DomainName.MaximumLength + 366 UserName.MaximumLength + 367 Password.MaximumLength; 368 369 AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), 370 HEAP_ZERO_MEMORY, 371 AuthInfoLength); 372 if (AuthInfo == NULL) 373 { 374 Status = STATUS_INSUFFICIENT_RESOURCES; 375 goto done; 376 } 377 378 AuthInfo->MessageType = MsV1_0InteractiveLogon; 379 380 Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON); 381 382 AuthInfo->LogonDomainName.Length = DomainName.Length; 383 AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength; 384 AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr; 385 if (DomainName.MaximumLength > 0) 386 { 387 RtlCopyMemory(AuthInfo->LogonDomainName.Buffer, 388 DomainName.Buffer, 389 DomainName.MaximumLength); 390 391 Ptr += DomainName.MaximumLength; 392 } 393 394 AuthInfo->UserName.Length = UserName.Length; 395 AuthInfo->UserName.MaximumLength = UserName.MaximumLength; 396 AuthInfo->UserName.Buffer = (PWCHAR)Ptr; 397 if (UserName.MaximumLength > 0) 398 RtlCopyMemory(AuthInfo->UserName.Buffer, 399 UserName.Buffer, 400 UserName.MaximumLength); 401 402 Ptr += UserName.MaximumLength; 403 404 AuthInfo->Password.Length = Password.Length; 405 AuthInfo->Password.MaximumLength = Password.MaximumLength; 406 AuthInfo->Password.Buffer = (PWCHAR)Ptr; 407 if (Password.MaximumLength > 0) 408 RtlCopyMemory(AuthInfo->Password.Buffer, 409 Password.Buffer, 410 Password.MaximumLength); 411 412 /* Create the Logon SID*/ 413 AllocateLocallyUniqueId(&LogonId); 414 Status = RtlAllocateAndInitializeSid(&SystemAuthority, 415 SECURITY_LOGON_IDS_RID_COUNT, 416 SECURITY_LOGON_IDS_RID, 417 LogonId.HighPart, 418 LogonId.LowPart, 419 SECURITY_NULL_RID, 420 SECURITY_NULL_RID, 421 SECURITY_NULL_RID, 422 SECURITY_NULL_RID, 423 SECURITY_NULL_RID, 424 &LogonSid); 425 if (!NT_SUCCESS(Status)) 426 goto done; 427 428 /* Create the Local SID*/ 429 Status = RtlAllocateAndInitializeSid(&LocalAuthority, 430 1, 431 SECURITY_LOCAL_RID, 432 SECURITY_NULL_RID, 433 SECURITY_NULL_RID, 434 SECURITY_NULL_RID, 435 SECURITY_NULL_RID, 436 SECURITY_NULL_RID, 437 SECURITY_NULL_RID, 438 SECURITY_NULL_RID, 439 &LocalSid); 440 if (!NT_SUCCESS(Status)) 441 goto done; 442 443 /* Allocate and set the token groups */ 444 TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(), 445 HEAP_ZERO_MEMORY, 446 sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES))); 447 if (TokenGroups == NULL) 448 { 449 Status = STATUS_INSUFFICIENT_RESOURCES; 450 goto done; 451 } 452 453 TokenGroups->GroupCount = 2; 454 TokenGroups->Groups[0].Sid = LogonSid; 455 TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | 456 SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID; 457 TokenGroups->Groups[1].Sid = LocalSid; 458 TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | 459 SE_GROUP_ENABLED_BY_DEFAULT; 460 461 /* Set the token source */ 462 strncpy(TokenSource.SourceName, "Advapi ", sizeof(TokenSource.SourceName)); 463 AllocateLocallyUniqueId(&TokenSource.SourceIdentifier); 464 465 Status = LsaLogonUser(LsaHandle, 466 &OriginName, 467 LogonType, 468 AuthenticationPackage, 469 (PVOID)AuthInfo, 470 AuthInfoLength, 471 TokenGroups, 472 &TokenSource, 473 (PVOID*)&ProfileBuffer, 474 &ProfileBufferLength, 475 &Luid, 476 &TokenHandle, 477 &QuotaLimits, 478 &SubStatus); 479 if (!NT_SUCCESS(Status)) 480 { 481 ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status); 482 goto done; 483 } 484 485 if (ProfileBuffer != NULL) 486 { 487 TRACE("ProfileBuffer: %p\n", ProfileBuffer); 488 TRACE("MessageType: %u\n", ProfileBuffer->MessageType); 489 490 TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer); 491 TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer); 492 493 TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer); 494 TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer); 495 } 496 497 TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart); 498 499 if (TokenHandle != NULL) 500 { 501 TRACE("TokenHandle: %p\n", TokenHandle); 502 } 503 504 *phToken = TokenHandle; 505 506 done: 507 if (ProfileBuffer != NULL) 508 LsaFreeReturnBuffer(ProfileBuffer); 509 510 if (!NT_SUCCESS(Status)) 511 { 512 if (TokenHandle != NULL) 513 CloseHandle(TokenHandle); 514 } 515 516 if (TokenGroups != NULL) 517 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups); 518 519 if (LocalSid != NULL) 520 RtlFreeSid(LocalSid); 521 522 if (LogonSid != NULL) 523 RtlFreeSid(LogonSid); 524 525 if (AuthInfo != NULL) 526 RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo); 527 528 if (!NT_SUCCESS(Status)) 529 { 530 SetLastError(RtlNtStatusToDosError(Status)); 531 return FALSE; 532 } 533 534 return TRUE; 535 } 536 537 /* EOF */ 538