xref: /reactos/dll/win32/msgina/lsa.c (revision 1734f297)
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 NTSTATUS
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 STATUS_SUCCESS;
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 Status;
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     }
47 
48     return Status;
49 }
50 
51 static const CHAR User32TokenSourceName[] = "User32  ";
52 C_ASSERT(sizeof(User32TokenSourceName) == RTL_FIELD_SIZE(TOKEN_SOURCE, SourceName) + 1);
53 
54 NTSTATUS
55 MyLogonUser(
56     HANDLE LsaHandle,
57     ULONG AuthenticationPackage,
58     LPWSTR lpszUsername,
59     LPWSTR lpszDomain,
60     LPWSTR lpszPassword,
61     PHANDLE phToken,
62     PNTSTATUS SubStatus)
63 {
64     SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
65     SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
66     PSID LogonSid = NULL;
67     PSID LocalSid = NULL;
68     LSA_STRING OriginName;
69     UNICODE_STRING DomainName;
70     UNICODE_STRING UserName;
71     UNICODE_STRING Password;
72     PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL;
73     ULONG AuthInfoLength;
74     ULONG_PTR Ptr;
75     TOKEN_SOURCE TokenSource;
76     PTOKEN_GROUPS TokenGroups = NULL;
77     PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL;
78     ULONG ProfileBufferLength = 0;
79     LUID Luid = {0, 0};
80     LUID LogonId = {0, 0};
81     HANDLE TokenHandle = NULL;
82     QUOTA_LIMITS QuotaLimits;
83     NTSTATUS Status;
84 
85     *phToken = NULL;
86 
87     RtlInitAnsiString((PANSI_STRING)&OriginName,
88                       "MSGINA Logon");
89 
90     RtlInitUnicodeString(&DomainName,
91                          lpszDomain);
92 
93     RtlInitUnicodeString(&UserName,
94                          lpszUsername);
95 
96     RtlInitUnicodeString(&Password,
97                          lpszPassword);
98 
99     AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+
100                      DomainName.MaximumLength +
101                      UserName.MaximumLength +
102                      Password.MaximumLength;
103 
104     AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
105                                HEAP_ZERO_MEMORY,
106                                AuthInfoLength);
107     if (AuthInfo == NULL)
108     {
109         Status = STATUS_INSUFFICIENT_RESOURCES;
110         goto done;
111     }
112 
113     AuthInfo->MessageType = MsV1_0InteractiveLogon;
114 
115     Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON);
116 
117     AuthInfo->LogonDomainName.Length = DomainName.Length;
118     AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength;
119     AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr;
120     if (DomainName.MaximumLength > 0)
121     {
122         RtlCopyMemory(AuthInfo->LogonDomainName.Buffer,
123                       DomainName.Buffer,
124                       DomainName.MaximumLength);
125 
126         Ptr += DomainName.MaximumLength;
127     }
128 
129     AuthInfo->UserName.Length = UserName.Length;
130     AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
131     AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
132     if (UserName.MaximumLength > 0)
133         RtlCopyMemory(AuthInfo->UserName.Buffer,
134                       UserName.Buffer,
135                       UserName.MaximumLength);
136 
137     Ptr += UserName.MaximumLength;
138 
139     AuthInfo->Password.Length = Password.Length;
140     AuthInfo->Password.MaximumLength = Password.MaximumLength;
141     AuthInfo->Password.Buffer = (PWCHAR)Ptr;
142     if (Password.MaximumLength > 0)
143         RtlCopyMemory(AuthInfo->Password.Buffer,
144                       Password.Buffer,
145                       Password.MaximumLength);
146 
147     /* Create the Logon SID*/
148     AllocateLocallyUniqueId(&LogonId);
149     Status = RtlAllocateAndInitializeSid(&SystemAuthority,
150                                          SECURITY_LOGON_IDS_RID_COUNT,
151                                          SECURITY_LOGON_IDS_RID,
152                                          LogonId.HighPart,
153                                          LogonId.LowPart,
154                                          SECURITY_NULL_RID,
155                                          SECURITY_NULL_RID,
156                                          SECURITY_NULL_RID,
157                                          SECURITY_NULL_RID,
158                                          SECURITY_NULL_RID,
159                                          &LogonSid);
160     if (!NT_SUCCESS(Status))
161         goto done;
162 
163     /* Create the Local SID*/
164     Status = RtlAllocateAndInitializeSid(&LocalAuthority,
165                                          1,
166                                          SECURITY_LOCAL_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                                          SECURITY_NULL_RID,
174                                          &LocalSid);
175     if (!NT_SUCCESS(Status))
176         goto done;
177 
178     /* Allocate and set the token groups */
179     TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(),
180                                   HEAP_ZERO_MEMORY,
181                                   sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES)));
182     if (TokenGroups == NULL)
183     {
184         Status = STATUS_INSUFFICIENT_RESOURCES;
185         goto done;
186     }
187 
188     TokenGroups->GroupCount = 2;
189     TokenGroups->Groups[0].Sid = LogonSid;
190     TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
191                                         SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID;
192     TokenGroups->Groups[1].Sid = LocalSid;
193     TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
194                                         SE_GROUP_ENABLED_BY_DEFAULT;
195 
196     /* Set the token source */
197     RtlCopyMemory(TokenSource.SourceName, User32TokenSourceName, sizeof(TokenSource.SourceName));
198     AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
199 
200     Status = LsaLogonUser(LsaHandle,
201                           &OriginName,
202                           Interactive,
203                           AuthenticationPackage,
204                           (PVOID)AuthInfo,
205                           AuthInfoLength,
206                           TokenGroups,
207                           &TokenSource,
208                           (PVOID*)&ProfileBuffer,
209                           &ProfileBufferLength,
210                           &Luid,
211                           &TokenHandle,
212                           &QuotaLimits,
213                           SubStatus);
214     if (!NT_SUCCESS(Status))
215     {
216         ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status);
217         goto done;
218     }
219 
220     if (ProfileBuffer != NULL)
221     {
222         TRACE("ProfileBuffer: %p\n", ProfileBuffer);
223         TRACE("MessageType: %u\n", ProfileBuffer->MessageType);
224 
225         TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer);
226         TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer);
227 
228         TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer);
229         TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer);
230     }
231 
232     TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);
233 
234     if (TokenHandle != NULL)
235     {
236         TRACE("TokenHandle: %p\n", TokenHandle);
237     }
238 
239     *phToken = TokenHandle;
240 
241 done:
242     if (ProfileBuffer != NULL)
243         LsaFreeReturnBuffer(ProfileBuffer);
244 
245     if (!NT_SUCCESS(Status))
246     {
247         if (TokenHandle != NULL)
248             CloseHandle(TokenHandle);
249     }
250 
251     if (TokenGroups != NULL)
252         RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);
253 
254     if (LocalSid != NULL)
255         RtlFreeSid(LocalSid);
256 
257     if (LogonSid != NULL)
258         RtlFreeSid(LogonSid);
259 
260     if (AuthInfo != NULL)
261         RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);
262 
263     return Status;
264 }
265 
266 /* EOF */
267