d1fa3339268953bbae5c727a859a32a835ecce2c
[reactos.git] / reactos / dll / win32 / advapi32 / misc / logon.c
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 NTSTATUS SubStatus = STATUS_SUCCESS;
320 NTSTATUS Status;
321
322 *phToken = NULL;
323
324 if (LsaHandle == NULL)
325 {
326 Status = OpenLogonLsaHandle();
327 if (!NT_SUCCESS(Status))
328 return Status;
329 }
330
331 RtlInitAnsiString((PANSI_STRING)&OriginName,
332 "Testapp");
333
334 RtlInitUnicodeString(&DomainName,
335 lpszDomain);
336
337 RtlInitUnicodeString(&UserName,
338 lpszUsername);
339
340 RtlInitUnicodeString(&Password,
341 lpszPassword);
342
343 AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+
344 DomainName.MaximumLength +
345 UserName.MaximumLength +
346 Password.MaximumLength;
347
348 AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
349 HEAP_ZERO_MEMORY,
350 AuthInfoLength);
351 if (AuthInfo == NULL)
352 {
353 Status = STATUS_INSUFFICIENT_RESOURCES;
354 goto done;
355 }
356
357 AuthInfo->MessageType = MsV1_0InteractiveLogon;
358
359 Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON);
360
361 AuthInfo->LogonDomainName.Length = DomainName.Length;
362 AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength;
363 AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr;
364 if (DomainName.MaximumLength > 0)
365 {
366 RtlCopyMemory(AuthInfo->LogonDomainName.Buffer,
367 DomainName.Buffer,
368 DomainName.MaximumLength);
369
370 Ptr += DomainName.MaximumLength;
371 }
372
373 AuthInfo->UserName.Length = UserName.Length;
374 AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
375 AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
376 if (UserName.MaximumLength > 0)
377 RtlCopyMemory(AuthInfo->UserName.Buffer,
378 UserName.Buffer,
379 UserName.MaximumLength);
380
381 Ptr += UserName.MaximumLength;
382
383 AuthInfo->Password.Length = Password.Length;
384 AuthInfo->Password.MaximumLength = Password.MaximumLength;
385 AuthInfo->Password.Buffer = (PWCHAR)Ptr;
386 if (Password.MaximumLength > 0)
387 RtlCopyMemory(AuthInfo->Password.Buffer,
388 Password.Buffer,
389 Password.MaximumLength);
390
391 /* Create the Logon SID*/
392 AllocateLocallyUniqueId(&LogonId);
393 Status = RtlAllocateAndInitializeSid(&SystemAuthority,
394 SECURITY_LOGON_IDS_RID_COUNT,
395 SECURITY_LOGON_IDS_RID,
396 LogonId.HighPart,
397 LogonId.LowPart,
398 SECURITY_NULL_RID,
399 SECURITY_NULL_RID,
400 SECURITY_NULL_RID,
401 SECURITY_NULL_RID,
402 SECURITY_NULL_RID,
403 &LogonSid);
404 if (!NT_SUCCESS(Status))
405 goto done;
406
407 /* Create the Local SID*/
408 Status = RtlAllocateAndInitializeSid(&LocalAuthority,
409 1,
410 SECURITY_LOCAL_RID,
411 SECURITY_NULL_RID,
412 SECURITY_NULL_RID,
413 SECURITY_NULL_RID,
414 SECURITY_NULL_RID,
415 SECURITY_NULL_RID,
416 SECURITY_NULL_RID,
417 SECURITY_NULL_RID,
418 &LocalSid);
419 if (!NT_SUCCESS(Status))
420 goto done;
421
422 /* Allocate and set the token groups */
423 TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(),
424 HEAP_ZERO_MEMORY,
425 sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES)));
426 if (TokenGroups == NULL)
427 {
428 Status = STATUS_INSUFFICIENT_RESOURCES;
429 goto done;
430 }
431
432 TokenGroups->GroupCount = 2;
433 TokenGroups->Groups[0].Sid = LogonSid;
434 TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
435 SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID;
436 TokenGroups->Groups[1].Sid = LocalSid;
437 TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
438 SE_GROUP_ENABLED_BY_DEFAULT;
439
440 /* Set the token source */
441 strcpy(TokenSource.SourceName, "LogonUser");
442 AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
443
444 Status = LsaLogonUser(LsaHandle,
445 &OriginName,
446 Interactive,
447 AuthenticationPackage,
448 (PVOID)AuthInfo,
449 AuthInfoLength,
450 TokenGroups,
451 &TokenSource,
452 (PVOID*)&ProfileBuffer,
453 &ProfileBufferLength,
454 &Luid,
455 &TokenHandle,
456 &QuotaLimits,
457 &SubStatus);
458 if (!NT_SUCCESS(Status))
459 {
460 TRACE("LsaLogonUser failed (Status 0x%08lx)\n", Status);
461 goto done;
462 }
463
464 if (ProfileBuffer != NULL)
465 {
466 TRACE("ProfileBuffer: %p\n", ProfileBuffer);
467 TRACE("MessageType: %u\n", ProfileBuffer->MessageType);
468
469 TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer);
470 TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer);
471
472 TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer);
473 TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer);
474 }
475
476 TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);
477
478 if (TokenHandle != NULL)
479 {
480 TRACE("TokenHandle: %p\n", TokenHandle);
481 }
482
483 *phToken = TokenHandle;
484
485 done:
486 if (ProfileBuffer != NULL)
487 LsaFreeReturnBuffer(ProfileBuffer);
488
489 if (!NT_SUCCESS(Status))
490 {
491 if (TokenHandle != NULL)
492 CloseHandle(TokenHandle);
493 }
494
495 if (TokenGroups != NULL)
496 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);
497
498 if (LocalSid != NULL)
499 RtlFreeSid(LocalSid);
500
501 if (LogonSid != NULL)
502 RtlFreeSid(LogonSid);
503
504 if (AuthInfo != NULL)
505 RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);
506
507 if (!NT_SUCCESS(Status))
508 {
509 SetLastError(RtlNtStatusToDosError(Status));
510 return FALSE;
511 }
512
513 return TRUE;
514 }
515
516 /* EOF */