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 /* Create the process with a suspended main thread */ 109 if (!CreateProcessA(lpApplicationName, 110 lpCommandLine, 111 lpProcessAttributes, 112 lpThreadAttributes, 113 bInheritHandles, 114 dwCreationFlags | CREATE_SUSPENDED, 115 lpEnvironment, 116 lpCurrentDirectory, 117 lpStartupInfo, 118 lpProcessInformation)) 119 { 120 return FALSE; 121 } 122 123 AccessToken.Token = hToken; 124 AccessToken.Thread = NULL; 125 126 /* Set the new process token */ 127 Status = NtSetInformationProcess(lpProcessInformation->hProcess, 128 ProcessAccessToken, 129 (PVOID)&AccessToken, 130 sizeof(AccessToken)); 131 if (!NT_SUCCESS (Status)) 132 { 133 SetLastError(RtlNtStatusToDosError(Status)); 134 return FALSE; 135 } 136 137 /* Resume the main thread */ 138 if (!(dwCreationFlags & CREATE_SUSPENDED)) 139 { 140 ResumeThread(lpProcessInformation->hThread); 141 } 142 143 return TRUE; 144 } 145 146 147 /* 148 * @implemented 149 */ 150 BOOL WINAPI 151 CreateProcessAsUserW(HANDLE hToken, 152 LPCWSTR lpApplicationName, 153 LPWSTR lpCommandLine, 154 LPSECURITY_ATTRIBUTES lpProcessAttributes, 155 LPSECURITY_ATTRIBUTES lpThreadAttributes, 156 BOOL bInheritHandles, 157 DWORD dwCreationFlags, 158 LPVOID lpEnvironment, 159 LPCWSTR lpCurrentDirectory, 160 LPSTARTUPINFOW lpStartupInfo, 161 LPPROCESS_INFORMATION lpProcessInformation) 162 { 163 PROCESS_ACCESS_TOKEN AccessToken; 164 NTSTATUS Status; 165 166 /* Create the process with a suspended main thread */ 167 if (!CreateProcessW(lpApplicationName, 168 lpCommandLine, 169 lpProcessAttributes, 170 lpThreadAttributes, 171 bInheritHandles, 172 dwCreationFlags | CREATE_SUSPENDED, 173 lpEnvironment, 174 lpCurrentDirectory, 175 lpStartupInfo, 176 lpProcessInformation)) 177 { 178 return FALSE; 179 } 180 181 AccessToken.Token = hToken; 182 AccessToken.Thread = NULL; 183 184 /* Set the new process token */ 185 Status = NtSetInformationProcess(lpProcessInformation->hProcess, 186 ProcessAccessToken, 187 (PVOID)&AccessToken, 188 sizeof(AccessToken)); 189 if (!NT_SUCCESS (Status)) 190 { 191 SetLastError(RtlNtStatusToDosError(Status)); 192 return FALSE; 193 } 194 195 /* Resume the main thread */ 196 if (!(dwCreationFlags & CREATE_SUSPENDED)) 197 { 198 ResumeThread(lpProcessInformation->hThread); 199 } 200 201 return TRUE; 202 } 203 204 /* 205 * @unimplemented 206 */ 207 BOOL WINAPI 208 CreateProcessWithLogonW(LPCWSTR lpUsername, 209 LPCWSTR lpDomain, 210 LPCWSTR lpPassword, 211 DWORD dwLogonFlags, 212 LPCWSTR lpApplicationName, 213 LPWSTR lpCommandLine, 214 DWORD dwCreationFlags, 215 LPVOID lpEnvironment, 216 LPCWSTR lpCurrentDirectory, 217 LPSTARTUPINFOW lpStartupInfo, 218 LPPROCESS_INFORMATION lpProcessInformation) 219 { 220 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain), 221 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName), 222 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), 223 lpStartupInfo, lpProcessInformation); 224 225 return FALSE; 226 } 227 228 /* 229 * @implemented 230 */ 231 BOOL WINAPI 232 LogonUserA(LPSTR lpszUsername, 233 LPSTR lpszDomain, 234 LPSTR lpszPassword, 235 DWORD dwLogonType, 236 DWORD dwLogonProvider, 237 PHANDLE phToken) 238 { 239 UNICODE_STRING UserName; 240 UNICODE_STRING Domain; 241 UNICODE_STRING Password; 242 BOOL ret = FALSE; 243 244 UserName.Buffer = NULL; 245 Domain.Buffer = NULL; 246 Password.Buffer = NULL; 247 248 if (!RtlCreateUnicodeStringFromAsciiz(&UserName, lpszUsername)) 249 { 250 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 251 goto UsernameDone; 252 } 253 254 if (!RtlCreateUnicodeStringFromAsciiz(&Domain, lpszDomain)) 255 { 256 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 257 goto DomainDone; 258 } 259 260 if (!RtlCreateUnicodeStringFromAsciiz(&Password, lpszPassword)) 261 { 262 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 263 goto PasswordDone; 264 } 265 266 ret = LogonUserW(UserName.Buffer, 267 Domain.Buffer, 268 Password.Buffer, 269 dwLogonType, 270 dwLogonProvider, 271 phToken); 272 273 if (Password.Buffer != NULL) 274 RtlFreeUnicodeString(&Password); 275 276 PasswordDone: 277 if (Domain.Buffer != NULL) 278 RtlFreeUnicodeString(&Domain); 279 280 DomainDone: 281 if (UserName.Buffer != NULL) 282 RtlFreeUnicodeString(&UserName); 283 284 UsernameDone: 285 return ret; 286 } 287 288 289 /* 290 * @implemented 291 */ 292 BOOL WINAPI 293 LogonUserW(LPWSTR lpszUsername, 294 LPWSTR lpszDomain, 295 LPWSTR lpszPassword, 296 DWORD dwLogonType, 297 DWORD dwLogonProvider, 298 PHANDLE phToken) 299 { 300 SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; 301 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; 302 PSID LogonSid = NULL; 303 PSID LocalSid = NULL; 304 LSA_STRING OriginName; 305 UNICODE_STRING DomainName; 306 UNICODE_STRING UserName; 307 UNICODE_STRING Password; 308 PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL; 309 ULONG AuthInfoLength; 310 ULONG_PTR Ptr; 311 TOKEN_SOURCE TokenSource; 312 PTOKEN_GROUPS TokenGroups = NULL; 313 PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL; 314 ULONG ProfileBufferLength = 0; 315 LUID Luid = {0, 0}; 316 LUID LogonId = {0, 0}; 317 HANDLE TokenHandle = NULL; 318 QUOTA_LIMITS QuotaLimits; 319 SECURITY_LOGON_TYPE LogonType; 320 NTSTATUS SubStatus = STATUS_SUCCESS; 321 NTSTATUS Status; 322 323 *phToken = NULL; 324 325 switch (dwLogonType) 326 { 327 case LOGON32_LOGON_INTERACTIVE: 328 LogonType = Interactive; 329 break; 330 331 case LOGON32_LOGON_NETWORK: 332 LogonType = Network; 333 break; 334 335 case LOGON32_LOGON_BATCH: 336 LogonType = Batch; 337 break; 338 339 case LOGON32_LOGON_SERVICE: 340 LogonType = Service; 341 break; 342 343 default: 344 ERR("Invalid logon type: %ul\n", dwLogonType); 345 Status = STATUS_INVALID_PARAMETER; 346 goto done; 347 } 348 349 if (LsaHandle == NULL) 350 { 351 Status = OpenLogonLsaHandle(); 352 if (!NT_SUCCESS(Status)) 353 goto done; 354 } 355 356 RtlInitAnsiString((PANSI_STRING)&OriginName, 357 "Advapi32 Logon"); 358 359 RtlInitUnicodeString(&DomainName, 360 lpszDomain); 361 362 RtlInitUnicodeString(&UserName, 363 lpszUsername); 364 365 RtlInitUnicodeString(&Password, 366 lpszPassword); 367 368 AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+ 369 DomainName.MaximumLength + 370 UserName.MaximumLength + 371 Password.MaximumLength; 372 373 AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), 374 HEAP_ZERO_MEMORY, 375 AuthInfoLength); 376 if (AuthInfo == NULL) 377 { 378 Status = STATUS_INSUFFICIENT_RESOURCES; 379 goto done; 380 } 381 382 AuthInfo->MessageType = MsV1_0InteractiveLogon; 383 384 Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON); 385 386 AuthInfo->LogonDomainName.Length = DomainName.Length; 387 AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength; 388 AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr; 389 if (DomainName.MaximumLength > 0) 390 { 391 RtlCopyMemory(AuthInfo->LogonDomainName.Buffer, 392 DomainName.Buffer, 393 DomainName.MaximumLength); 394 395 Ptr += DomainName.MaximumLength; 396 } 397 398 AuthInfo->UserName.Length = UserName.Length; 399 AuthInfo->UserName.MaximumLength = UserName.MaximumLength; 400 AuthInfo->UserName.Buffer = (PWCHAR)Ptr; 401 if (UserName.MaximumLength > 0) 402 RtlCopyMemory(AuthInfo->UserName.Buffer, 403 UserName.Buffer, 404 UserName.MaximumLength); 405 406 Ptr += UserName.MaximumLength; 407 408 AuthInfo->Password.Length = Password.Length; 409 AuthInfo->Password.MaximumLength = Password.MaximumLength; 410 AuthInfo->Password.Buffer = (PWCHAR)Ptr; 411 if (Password.MaximumLength > 0) 412 RtlCopyMemory(AuthInfo->Password.Buffer, 413 Password.Buffer, 414 Password.MaximumLength); 415 416 /* Create the Logon SID*/ 417 AllocateLocallyUniqueId(&LogonId); 418 Status = RtlAllocateAndInitializeSid(&SystemAuthority, 419 SECURITY_LOGON_IDS_RID_COUNT, 420 SECURITY_LOGON_IDS_RID, 421 LogonId.HighPart, 422 LogonId.LowPart, 423 SECURITY_NULL_RID, 424 SECURITY_NULL_RID, 425 SECURITY_NULL_RID, 426 SECURITY_NULL_RID, 427 SECURITY_NULL_RID, 428 &LogonSid); 429 if (!NT_SUCCESS(Status)) 430 goto done; 431 432 /* Create the Local SID*/ 433 Status = RtlAllocateAndInitializeSid(&LocalAuthority, 434 1, 435 SECURITY_LOCAL_RID, 436 SECURITY_NULL_RID, 437 SECURITY_NULL_RID, 438 SECURITY_NULL_RID, 439 SECURITY_NULL_RID, 440 SECURITY_NULL_RID, 441 SECURITY_NULL_RID, 442 SECURITY_NULL_RID, 443 &LocalSid); 444 if (!NT_SUCCESS(Status)) 445 goto done; 446 447 /* Allocate and set the token groups */ 448 TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(), 449 HEAP_ZERO_MEMORY, 450 sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES))); 451 if (TokenGroups == NULL) 452 { 453 Status = STATUS_INSUFFICIENT_RESOURCES; 454 goto done; 455 } 456 457 TokenGroups->GroupCount = 2; 458 TokenGroups->Groups[0].Sid = LogonSid; 459 TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | 460 SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID; 461 TokenGroups->Groups[1].Sid = LocalSid; 462 TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | 463 SE_GROUP_ENABLED_BY_DEFAULT; 464 465 /* Set the token source */ 466 strcpy(TokenSource.SourceName, "LogonUser"); 467 AllocateLocallyUniqueId(&TokenSource.SourceIdentifier); 468 469 Status = LsaLogonUser(LsaHandle, 470 &OriginName, 471 LogonType, 472 AuthenticationPackage, 473 (PVOID)AuthInfo, 474 AuthInfoLength, 475 TokenGroups, 476 &TokenSource, 477 (PVOID*)&ProfileBuffer, 478 &ProfileBufferLength, 479 &Luid, 480 &TokenHandle, 481 &QuotaLimits, 482 &SubStatus); 483 if (!NT_SUCCESS(Status)) 484 { 485 ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status); 486 goto done; 487 } 488 489 if (ProfileBuffer != NULL) 490 { 491 TRACE("ProfileBuffer: %p\n", ProfileBuffer); 492 TRACE("MessageType: %u\n", ProfileBuffer->MessageType); 493 494 TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer); 495 TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer); 496 497 TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer); 498 TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer); 499 } 500 501 TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart); 502 503 if (TokenHandle != NULL) 504 { 505 TRACE("TokenHandle: %p\n", TokenHandle); 506 } 507 508 *phToken = TokenHandle; 509 510 done: 511 if (ProfileBuffer != NULL) 512 LsaFreeReturnBuffer(ProfileBuffer); 513 514 if (!NT_SUCCESS(Status)) 515 { 516 if (TokenHandle != NULL) 517 CloseHandle(TokenHandle); 518 } 519 520 if (TokenGroups != NULL) 521 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups); 522 523 if (LocalSid != NULL) 524 RtlFreeSid(LocalSid); 525 526 if (LogonSid != NULL) 527 RtlFreeSid(LogonSid); 528 529 if (AuthInfo != NULL) 530 RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo); 531 532 if (!NT_SUCCESS(Status)) 533 { 534 SetLastError(RtlNtStatusToDosError(Status)); 535 return FALSE; 536 } 537 538 return TRUE; 539 } 540 541 /* EOF */ 542