[MSGINA]
[reactos.git] / reactos / dll / win32 / msgina / lsa.c
1 /*
2 * PROJECT: ReactOS msgina.dll
3 * FILE: dll/win32/msgina/gui.c
4 * PURPOSE: ReactOS Logon GINA DLL
5 * PROGRAMMER: Eric Kohl
6 */
7
8 #include "msgina.h"
9
10 BOOL
11 ConnectToLsa(
12 PGINA_CONTEXT pgContext)
13 {
14 LSA_STRING LogonProcessName;
15 LSA_STRING PackageName;
16 LSA_OPERATIONAL_MODE SecurityMode = 0;
17 NTSTATUS Status;
18
19 /* We are already connected to the LSA */
20 if (pgContext->LsaHandle != NULL)
21 return TRUE;
22
23 /* Connect to the LSA server */
24 RtlInitAnsiString((PANSI_STRING)&LogonProcessName,
25 "MSGINA");
26
27 Status = LsaRegisterLogonProcess(&LogonProcessName,
28 &pgContext->LsaHandle,
29 &SecurityMode);
30 if (!NT_SUCCESS(Status))
31 {
32 ERR("LsaRegisterLogonProcess failed (Status 0x%08lx)\n", Status);
33 return FALSE;
34 }
35
36 /* Get the authentication package */
37 RtlInitAnsiString((PANSI_STRING)&PackageName,
38 MSV1_0_PACKAGE_NAME);
39
40 Status = LsaLookupAuthenticationPackage(pgContext->LsaHandle,
41 &PackageName,
42 &pgContext->AuthenticationPackage);
43 if (!NT_SUCCESS(Status))
44 {
45 ERR("LsaLookupAuthenticationPackage failed (Status 0x%08lx)\n", Status);
46 return FALSE;
47 }
48
49 return TRUE;
50 }
51
52
53 BOOL
54 MyLogonUser(
55 HANDLE LsaHandle,
56 ULONG AuthenticationPackage,
57 LPWSTR lpszUsername,
58 LPWSTR lpszDomain,
59 LPWSTR lpszPassword,
60 PHANDLE phToken)
61 {
62 SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
63 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
64 PSID LogonSid = NULL;
65 PSID LocalSid = NULL;
66 LSA_STRING OriginName;
67 UNICODE_STRING DomainName;
68 UNICODE_STRING UserName;
69 UNICODE_STRING Password;
70 PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL;
71 ULONG AuthInfoLength;
72 ULONG_PTR Ptr;
73 TOKEN_SOURCE TokenSource;
74 PTOKEN_GROUPS TokenGroups = NULL;
75 PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL;
76 ULONG ProfileBufferLength = 0;
77 LUID Luid = {0, 0};
78 LUID LogonId = {0, 0};
79 HANDLE TokenHandle = NULL;
80 QUOTA_LIMITS QuotaLimits;
81 NTSTATUS SubStatus = STATUS_SUCCESS;
82 NTSTATUS Status;
83
84 *phToken = NULL;
85
86 RtlInitAnsiString((PANSI_STRING)&OriginName,
87 "MSGINA Logon");
88
89 RtlInitUnicodeString(&DomainName,
90 lpszDomain);
91
92 RtlInitUnicodeString(&UserName,
93 lpszUsername);
94
95 RtlInitUnicodeString(&Password,
96 lpszPassword);
97
98 AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+
99 DomainName.MaximumLength +
100 UserName.MaximumLength +
101 Password.MaximumLength;
102
103 AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
104 HEAP_ZERO_MEMORY,
105 AuthInfoLength);
106 if (AuthInfo == NULL)
107 {
108 Status = STATUS_INSUFFICIENT_RESOURCES;
109 goto done;
110 }
111
112 AuthInfo->MessageType = MsV1_0InteractiveLogon;
113
114 Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON);
115
116 AuthInfo->LogonDomainName.Length = DomainName.Length;
117 AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength;
118 AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr;
119 if (DomainName.MaximumLength > 0)
120 {
121 RtlCopyMemory(AuthInfo->LogonDomainName.Buffer,
122 DomainName.Buffer,
123 DomainName.MaximumLength);
124
125 Ptr += DomainName.MaximumLength;
126 }
127
128 AuthInfo->UserName.Length = UserName.Length;
129 AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
130 AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
131 if (UserName.MaximumLength > 0)
132 RtlCopyMemory(AuthInfo->UserName.Buffer,
133 UserName.Buffer,
134 UserName.MaximumLength);
135
136 Ptr += UserName.MaximumLength;
137
138 AuthInfo->Password.Length = Password.Length;
139 AuthInfo->Password.MaximumLength = Password.MaximumLength;
140 AuthInfo->Password.Buffer = (PWCHAR)Ptr;
141 if (Password.MaximumLength > 0)
142 RtlCopyMemory(AuthInfo->Password.Buffer,
143 Password.Buffer,
144 Password.MaximumLength);
145
146 /* Create the Logon SID*/
147 AllocateLocallyUniqueId(&LogonId);
148 Status = RtlAllocateAndInitializeSid(&SystemAuthority,
149 SECURITY_LOGON_IDS_RID_COUNT,
150 SECURITY_LOGON_IDS_RID,
151 LogonId.HighPart,
152 LogonId.LowPart,
153 SECURITY_NULL_RID,
154 SECURITY_NULL_RID,
155 SECURITY_NULL_RID,
156 SECURITY_NULL_RID,
157 SECURITY_NULL_RID,
158 &LogonSid);
159 if (!NT_SUCCESS(Status))
160 goto done;
161
162 /* Create the Local SID*/
163 Status = RtlAllocateAndInitializeSid(&LocalAuthority,
164 1,
165 SECURITY_LOCAL_RID,
166 SECURITY_NULL_RID,
167 SECURITY_NULL_RID,
168 SECURITY_NULL_RID,
169 SECURITY_NULL_RID,
170 SECURITY_NULL_RID,
171 SECURITY_NULL_RID,
172 SECURITY_NULL_RID,
173 &LocalSid);
174 if (!NT_SUCCESS(Status))
175 goto done;
176
177 /* Allocate and set the token groups */
178 TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(),
179 HEAP_ZERO_MEMORY,
180 sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES)));
181 if (TokenGroups == NULL)
182 {
183 Status = STATUS_INSUFFICIENT_RESOURCES;
184 goto done;
185 }
186
187 TokenGroups->GroupCount = 2;
188 TokenGroups->Groups[0].Sid = LogonSid;
189 TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
190 SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID;
191 TokenGroups->Groups[1].Sid = LocalSid;
192 TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
193 SE_GROUP_ENABLED_BY_DEFAULT;
194
195 /* Set the token source */
196 strcpy(TokenSource.SourceName, "LogonUser");
197 AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
198
199 Status = LsaLogonUser(LsaHandle,
200 &OriginName,
201 Interactive,
202 AuthenticationPackage,
203 (PVOID)AuthInfo,
204 AuthInfoLength,
205 TokenGroups,
206 &TokenSource,
207 (PVOID*)&ProfileBuffer,
208 &ProfileBufferLength,
209 &Luid,
210 &TokenHandle,
211 &QuotaLimits,
212 &SubStatus);
213 if (!NT_SUCCESS(Status))
214 {
215 ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status);
216 goto done;
217 }
218
219 if (ProfileBuffer != NULL)
220 {
221 TRACE("ProfileBuffer: %p\n", ProfileBuffer);
222 TRACE("MessageType: %u\n", ProfileBuffer->MessageType);
223
224 TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer);
225 TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer);
226
227 TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer);
228 TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer);
229 }
230
231 TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);
232
233 if (TokenHandle != NULL)
234 {
235 TRACE("TokenHandle: %p\n", TokenHandle);
236 }
237
238 *phToken = TokenHandle;
239
240 done:
241 if (ProfileBuffer != NULL)
242 LsaFreeReturnBuffer(ProfileBuffer);
243
244 if (!NT_SUCCESS(Status))
245 {
246 if (TokenHandle != NULL)
247 CloseHandle(TokenHandle);
248 }
249
250 if (TokenGroups != NULL)
251 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);
252
253 if (LocalSid != NULL)
254 RtlFreeSid(LocalSid);
255
256 if (LogonSid != NULL)
257 RtlFreeSid(LogonSid);
258
259 if (AuthInfo != NULL)
260 RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);
261
262 if (!NT_SUCCESS(Status))
263 {
264 SetLastError(RtlNtStatusToDosError(Status));
265 return FALSE;
266 }
267
268 return TRUE;
269 }
270
271 /* EOF */