[LSALIB]
[reactos.git] / reactos / sdk / lib / lsalib / lsa.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/lsalib/lsa.c
5 * PURPOSE: Client-side LSA functions
6 * UPDATE HISTORY:
7 * Created 05/08/00
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ndk/exfuncs.h>
13 #include <ndk/lpctypes.h>
14 #include <ndk/lpcfuncs.h>
15 #include <ndk/mmfuncs.h>
16 #include <ndk/rtlfuncs.h>
17 #include <ndk/obfuncs.h>
18 // #include <psdk/ntsecapi.h>
19 #include <lsass/lsass.h>
20
21 #define NDEBUG
22 #include <debug.h>
23
24 /* GLOBALS *******************************************************************/
25
26 // FIXME: Do we really need this?!
27 #if !defined(__NTOSKRNL__) && !defined(_NTOSKRNL_) && !defined(_NTSYSTEM_)
28 extern HANDLE Secur32Heap;
29 #endif
30
31 /* FUNCTIONS *****************************************************************/
32
33 /* This API is not defined and exported by NTOSKRNL */
34 #if !defined(__NTOSKRNL__) && !defined(_NTOSKRNL_) && !defined(_NTSYSTEM_)
35 /*
36 * @implemented
37 */
38 NTSTATUS
39 NTAPI
40 LsaConnectUntrusted(OUT PHANDLE LsaHandle)
41 {
42 NTSTATUS Status;
43 UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
44 SECURITY_QUALITY_OF_SERVICE SecurityQos;
45 LSA_CONNECTION_INFO ConnectInfo;
46 ULONG ConnectInfoLength = sizeof(ConnectInfo);
47
48 DPRINT("LsaConnectUntrusted(%p)\n", LsaHandle);
49
50 // TODO: Wait on L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED" event
51 // for the LSA server to be ready, and because we are untrusted,
52 // we may need to impersonate ourselves before!
53
54 RtlInitUnicodeString(&PortName, L"\\LsaAuthenticationPort");
55
56 SecurityQos.Length = sizeof(SecurityQos);
57 SecurityQos.ImpersonationLevel = SecurityIdentification;
58 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
59 SecurityQos.EffectiveOnly = TRUE;
60
61 RtlZeroMemory(&ConnectInfo,
62 ConnectInfoLength);
63
64 ConnectInfo.CreateContext = TRUE;
65
66 Status = ZwConnectPort(LsaHandle,
67 &PortName,
68 &SecurityQos,
69 NULL,
70 NULL,
71 NULL,
72 &ConnectInfo,
73 &ConnectInfoLength);
74 if (!NT_SUCCESS(Status))
75 {
76 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status);
77 return Status;
78 }
79
80 if (!NT_SUCCESS(ConnectInfo.Status))
81 {
82 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
83 }
84
85 return ConnectInfo.Status;
86 }
87 #endif
88
89 /*
90 * @implemented
91 */
92 NTSTATUS
93 NTAPI
94 LsaCallAuthenticationPackage(IN HANDLE LsaHandle,
95 IN ULONG AuthenticationPackage,
96 IN PVOID ProtocolSubmitBuffer,
97 IN ULONG SubmitBufferLength,
98 OUT PVOID *ProtocolReturnBuffer,
99 OUT PULONG ReturnBufferLength,
100 OUT PNTSTATUS ProtocolStatus)
101 {
102 NTSTATUS Status;
103 LSA_API_MSG ApiMessage;
104
105 DPRINT1("LsaCallAuthenticationPackage()\n");
106
107 ApiMessage.ApiNumber = LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE;
108 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.CallAuthenticationPackage);
109 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
110 ApiMessage.h.u2.ZeroInit = 0;
111
112 ApiMessage.CallAuthenticationPackage.Request.AuthenticationPackage = AuthenticationPackage;
113 ApiMessage.CallAuthenticationPackage.Request.ProtocolSubmitBuffer = ProtocolSubmitBuffer;
114 ApiMessage.CallAuthenticationPackage.Request.SubmitBufferLength = SubmitBufferLength;
115
116 Status = ZwRequestWaitReplyPort(LsaHandle,
117 (PPORT_MESSAGE)&ApiMessage,
118 (PPORT_MESSAGE)&ApiMessage);
119 if (!NT_SUCCESS(Status))
120 {
121 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
122 return Status;
123 }
124
125 if (!NT_SUCCESS(ApiMessage.Status))
126 {
127 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
128 return ApiMessage.Status;
129 }
130
131 *ProtocolReturnBuffer = ApiMessage.CallAuthenticationPackage.Reply.ProtocolReturnBuffer;
132 *ReturnBufferLength = ApiMessage.CallAuthenticationPackage.Reply.ReturnBufferLength;
133 *ProtocolStatus = ApiMessage.CallAuthenticationPackage.Reply.ProtocolStatus;
134
135 return Status;
136 }
137
138
139 /*
140 * @implemented
141 */
142 NTSTATUS
143 NTAPI
144 LsaFreeReturnBuffer(IN PVOID Buffer)
145 {
146 SIZE_T Size = 0;
147 return ZwFreeVirtualMemory(NtCurrentProcess(),
148 &Buffer,
149 &Size,
150 MEM_RELEASE);
151 }
152
153
154 /*
155 * @implemented
156 */
157 NTSTATUS
158 NTAPI
159 LsaLookupAuthenticationPackage(IN HANDLE LsaHandle,
160 IN PLSA_STRING PackageName,
161 OUT PULONG AuthenticationPackage)
162 {
163 NTSTATUS Status;
164 LSA_API_MSG ApiMessage;
165
166 /* Check the package name length */
167 if (PackageName->Length > LSASS_MAX_PACKAGE_NAME_LENGTH)
168 {
169 return STATUS_NAME_TOO_LONG;
170 }
171
172 ApiMessage.ApiNumber = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE;
173 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LookupAuthenticationPackage);
174 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
175 ApiMessage.h.u2.ZeroInit = 0;
176
177 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength = PackageName->Length;
178 strncpy(ApiMessage.LookupAuthenticationPackage.Request.PackageName,
179 PackageName->Buffer,
180 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength);
181 ApiMessage.LookupAuthenticationPackage.Request.PackageName[ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength] = ANSI_NULL;
182
183 Status = ZwRequestWaitReplyPort(LsaHandle,
184 (PPORT_MESSAGE)&ApiMessage,
185 (PPORT_MESSAGE)&ApiMessage);
186 if (!NT_SUCCESS(Status))
187 {
188 return Status;
189 }
190
191 if (!NT_SUCCESS(ApiMessage.Status))
192 {
193 return ApiMessage.Status;
194 }
195
196 *AuthenticationPackage = ApiMessage.LookupAuthenticationPackage.Reply.Package;
197
198 return Status;
199 }
200
201
202 /*
203 * @implemented
204 */
205 NTSTATUS
206 NTAPI
207 LsaLogonUser(IN HANDLE LsaHandle,
208 IN PLSA_STRING OriginName,
209 IN SECURITY_LOGON_TYPE LogonType,
210 IN ULONG AuthenticationPackage,
211 IN PVOID AuthenticationInformation,
212 IN ULONG AuthenticationInformationLength,
213 IN PTOKEN_GROUPS LocalGroups OPTIONAL,
214 IN PTOKEN_SOURCE SourceContext,
215 OUT PVOID *ProfileBuffer,
216 OUT PULONG ProfileBufferLength,
217 OUT PLUID LogonId,
218 OUT PHANDLE Token,
219 OUT PQUOTA_LIMITS Quotas,
220 OUT PNTSTATUS SubStatus)
221 {
222 NTSTATUS Status;
223 LSA_API_MSG ApiMessage;
224
225 ApiMessage.ApiNumber = LSASS_REQUEST_LOGON_USER;
226 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LogonUser);
227 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
228 ApiMessage.h.u2.ZeroInit = 0;
229
230 ApiMessage.LogonUser.Request.OriginName = *OriginName;
231 ApiMessage.LogonUser.Request.LogonType = LogonType;
232 ApiMessage.LogonUser.Request.AuthenticationPackage = AuthenticationPackage;
233 ApiMessage.LogonUser.Request.AuthenticationInformation = AuthenticationInformation;
234 ApiMessage.LogonUser.Request.AuthenticationInformationLength = AuthenticationInformationLength;
235 ApiMessage.LogonUser.Request.LocalGroups = LocalGroups;
236 if (LocalGroups != NULL)
237 ApiMessage.LogonUser.Request.LocalGroupsCount = LocalGroups->GroupCount;
238 else
239 ApiMessage.LogonUser.Request.LocalGroupsCount = 0;
240 ApiMessage.LogonUser.Request.SourceContext = *SourceContext;
241
242 Status = ZwRequestWaitReplyPort(LsaHandle,
243 (PPORT_MESSAGE)&ApiMessage,
244 (PPORT_MESSAGE)&ApiMessage);
245 if (!NT_SUCCESS(Status))
246 {
247 return Status;
248 }
249
250 *SubStatus = ApiMessage.LogonUser.Reply.SubStatus;
251
252 if (!NT_SUCCESS(ApiMessage.Status))
253 {
254 return ApiMessage.Status;
255 }
256
257 *ProfileBuffer = ApiMessage.LogonUser.Reply.ProfileBuffer;
258 *ProfileBufferLength = ApiMessage.LogonUser.Reply.ProfileBufferLength;
259 *LogonId = ApiMessage.LogonUser.Reply.LogonId;
260 *Token = ApiMessage.LogonUser.Reply.Token;
261 *Quotas = ApiMessage.LogonUser.Reply.Quotas;
262
263 return Status;
264 }
265
266
267 /*
268 * @implemented
269 */
270 NTSTATUS
271 NTAPI
272 LsaRegisterLogonProcess(IN PLSA_STRING LogonProcessName,
273 OUT PHANDLE LsaHandle,
274 OUT PLSA_OPERATIONAL_MODE OperationalMode)
275 {
276 NTSTATUS Status;
277 #if 0
278 HANDLE EventHandle;
279 #endif
280 UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
281 #if 0
282 OBJECT_ATTRIBUTES ObjectAttributes;
283 #endif
284 SECURITY_QUALITY_OF_SERVICE SecurityQos;
285 LSA_CONNECTION_INFO ConnectInfo;
286 ULONG ConnectInfoLength = sizeof(ConnectInfo);
287
288 DPRINT("LsaRegisterLogonProcess()\n");
289
290 /* Check the logon process name length */
291 if (LogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH)
292 return STATUS_NAME_TOO_LONG;
293
294 #if 0
295 /*
296 * First check whether the LSA server is ready:
297 * open the LSA event and wait on it.
298 */
299 // Note that we just reuse the 'PortName' variable here.
300 RtlInitUnicodeString(&PortName, L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
301 InitializeObjectAttributes(&ObjectAttributes,
302 &PortName,
303 OBJ_CASE_INSENSITIVE,
304 NULL,
305 NULL);
306 Status = NtOpenEvent(&EventHandle, SYNCHRONIZE, &ObjectAttributes);
307 if (!NT_SUCCESS(Status))
308 {
309 DPRINT1("NtOpenEvent failed (Status 0x%08lx)\n", Status);
310 return Status;
311 }
312
313 Status = NtWaitForSingleObject(EventHandle, TRUE, NULL);
314 NtClose(EventHandle);
315 if (!NT_SUCCESS(Status))
316 {
317 DPRINT1("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status);
318 return Status;
319 }
320 #endif
321
322 /* Now attempt the connection */
323 RtlInitUnicodeString(&PortName, L"\\LsaAuthenticationPort");
324
325 SecurityQos.Length = sizeof(SecurityQos);
326 SecurityQos.ImpersonationLevel = SecurityIdentification;
327 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
328 SecurityQos.EffectiveOnly = TRUE;
329
330 strncpy(ConnectInfo.LogonProcessNameBuffer,
331 LogonProcessName->Buffer,
332 LogonProcessName->Length);
333 ConnectInfo.Length = LogonProcessName->Length;
334 ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = ANSI_NULL;
335 ConnectInfo.CreateContext = TRUE;
336
337 Status = ZwConnectPort(LsaHandle,
338 &PortName,
339 &SecurityQos,
340 NULL,
341 NULL,
342 NULL,
343 &ConnectInfo,
344 &ConnectInfoLength);
345 if (!NT_SUCCESS(Status))
346 {
347 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status);
348 return Status;
349 }
350
351 DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo.OperationalMode);
352 *OperationalMode = ConnectInfo.OperationalMode;
353
354 if (!NT_SUCCESS(ConnectInfo.Status))
355 {
356 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
357 }
358
359 return ConnectInfo.Status;
360 }
361
362
363 /*
364 * @implemented
365 */
366 NTSTATUS
367 NTAPI
368 LsaDeregisterLogonProcess(IN HANDLE LsaHandle)
369 {
370 NTSTATUS Status;
371 LSA_API_MSG ApiMessage;
372
373 DPRINT("LsaDeregisterLogonProcess()\n");
374
375 ApiMessage.ApiNumber = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
376 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.DeregisterLogonProcess);
377 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
378 ApiMessage.h.u2.ZeroInit = 0;
379
380 Status = ZwRequestWaitReplyPort(LsaHandle,
381 (PPORT_MESSAGE)&ApiMessage,
382 (PPORT_MESSAGE)&ApiMessage);
383 if (!NT_SUCCESS(Status))
384 {
385 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
386 return Status;
387 }
388
389 if (!NT_SUCCESS(ApiMessage.Status))
390 {
391 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
392 return ApiMessage.Status;
393 }
394
395 NtClose(LsaHandle);
396
397 DPRINT("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status);
398
399 return Status;
400 }