[LSALIB]
[reactos.git] / reactos / 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/lpctypes.h>
13 #include <ndk/lpcfuncs.h>
14 #include <ndk/mmfuncs.h>
15 #include <ndk/rtlfuncs.h>
16 #include <ndk/obfuncs.h>
17 #include <psdk/ntsecapi.h>
18 #include <lsass/lsass.h>
19
20 #define NDEBUG
21 #include <debug.h>
22
23 /* GLOBALS *******************************************************************/
24
25 extern HANDLE Secur32Heap;
26
27 /* FUNCTIONS *****************************************************************/
28
29 /*
30 * @implemented
31 */
32 NTSTATUS WINAPI
33 LsaDeregisterLogonProcess(HANDLE LsaHandle)
34 {
35 LSA_API_MSG ApiMessage;
36 NTSTATUS Status;
37
38 DPRINT1("LsaDeregisterLogonProcess()\n");
39
40 ApiMessage.ApiNumber = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
41 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.DeregisterLogonProcess);
42 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
43 ApiMessage.h.u2.ZeroInit = 0;
44
45 Status = ZwRequestWaitReplyPort(LsaHandle,
46 (PPORT_MESSAGE)&ApiMessage,
47 (PPORT_MESSAGE)&ApiMessage);
48 if (!NT_SUCCESS(Status))
49 {
50 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
51 return Status;
52 }
53
54 if (!NT_SUCCESS(ApiMessage.Status))
55 {
56 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
57 return ApiMessage.Status;
58 }
59
60 NtClose(LsaHandle);
61
62 DPRINT1("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status);
63
64 return Status;
65 }
66
67
68 /*
69 * @unimplemented
70 */
71 NTSTATUS WINAPI
72 LsaConnectUntrusted(PHANDLE LsaHandle)
73 {
74 UNIMPLEMENTED;
75 return STATUS_NOT_IMPLEMENTED;
76 }
77
78
79 /*
80 * @implemented
81 */
82 NTSTATUS WINAPI
83 LsaCallAuthenticationPackage(HANDLE LsaHandle,
84 ULONG AuthenticationPackage,
85 PVOID ProtocolSubmitBuffer,
86 ULONG SubmitBufferLength,
87 PVOID *ProtocolReturnBuffer,
88 PULONG ReturnBufferLength,
89 PNTSTATUS ProtocolStatus)
90 {
91 LSA_API_MSG ApiMessage;
92 NTSTATUS Status;
93
94 DPRINT1("LsaCallAuthenticationPackage()\n");
95
96 ApiMessage.ApiNumber = LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE;
97 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.CallAuthenticationPackage);
98 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
99 ApiMessage.h.u2.ZeroInit = 0;
100
101 ApiMessage.CallAuthenticationPackage.Request.AuthenticationPackage = AuthenticationPackage;
102 ApiMessage.CallAuthenticationPackage.Request.ProtocolSubmitBuffer = ProtocolSubmitBuffer;
103 ApiMessage.CallAuthenticationPackage.Request.SubmitBufferLength = SubmitBufferLength;
104
105 Status = ZwRequestWaitReplyPort(LsaHandle,
106 (PPORT_MESSAGE)&ApiMessage,
107 (PPORT_MESSAGE)&ApiMessage);
108 if (!NT_SUCCESS(Status))
109 {
110 DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
111 return Status;
112 }
113
114 if (!NT_SUCCESS(ApiMessage.Status))
115 {
116 DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
117 return ApiMessage.Status;
118 }
119
120 *ProtocolReturnBuffer = ApiMessage.CallAuthenticationPackage.Reply.ProtocolReturnBuffer;
121 *ReturnBufferLength = ApiMessage.CallAuthenticationPackage.Reply.ReturnBufferLength;
122 *ProtocolStatus = ApiMessage.CallAuthenticationPackage.Reply.ProtocolStatus;
123
124 return Status;
125
126
127 #if 0
128 PLSASS_REQUEST Request;
129 PLSASS_REPLY Reply;
130 LSASS_REQUEST RawRequest;
131 LSASS_REPLY RawReply;
132 NTSTATUS Status;
133 ULONG OutBufferSize;
134
135 Request = (PLSASS_REQUEST)&RawRequest;
136 Reply = (PLSASS_REPLY)&RawReply;
137
138 Request->Header.u1.s1.DataLength = sizeof(LSASS_REQUEST) + SubmitBufferLength -
139 sizeof(PORT_MESSAGE);
140 Request->Header.u1.s1.TotalLength =
141 Request->Header.u1.s1.DataLength + sizeof(PORT_MESSAGE);
142 Request->Type = LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE;
143 Request->d.CallAuthenticationPackageRequest.AuthenticationPackage =
144 AuthenticationPackage;
145 Request->d.CallAuthenticationPackageRequest.InBufferLength =
146 SubmitBufferLength;
147 memcpy(Request->d.CallAuthenticationPackageRequest.InBuffer,
148 ProtocolSubmitBuffer,
149 SubmitBufferLength);
150
151 Status = ZwRequestWaitReplyPort(LsaHandle,
152 &Request->Header,
153 &Reply->Header);
154 if (!NT_SUCCESS(Status))
155 {
156 return Status;
157 }
158
159 if (!NT_SUCCESS(Reply->Status))
160 {
161 return Reply->Status;
162 }
163
164 OutBufferSize = Reply->d.CallAuthenticationPackageReply.OutBufferLength;
165 *ProtocolReturnBuffer = RtlAllocateHeap(Secur32Heap,
166 0,
167 OutBufferSize);
168 *ReturnBufferLength = OutBufferSize;
169 memcpy(*ProtocolReturnBuffer,
170 Reply->d.CallAuthenticationPackageReply.OutBuffer,
171 *ReturnBufferLength);
172
173 return Status;
174 #endif
175 }
176
177
178 /*
179 * @implemented
180 */
181 NTSTATUS WINAPI
182 LsaFreeReturnBuffer(PVOID Buffer)
183 {
184 ULONG Length = 0;
185
186 return ZwFreeVirtualMemory(NtCurrentProcess(),
187 &Buffer,
188 &Length,
189 MEM_RELEASE);
190 }
191
192
193 /*
194 * @implemented
195 */
196 NTSTATUS WINAPI
197 LsaLookupAuthenticationPackage(HANDLE LsaHandle,
198 PLSA_STRING PackageName,
199 PULONG AuthenticationPackage)
200 {
201 LSA_API_MSG ApiMessage;
202 NTSTATUS Status;
203
204 /* Check the package name length */
205 if (PackageName->Length > LSASS_MAX_PACKAGE_NAME_LENGTH)
206 {
207 return STATUS_NAME_TOO_LONG;
208 }
209
210 ApiMessage.ApiNumber = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE;
211 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LookupAuthenticationPackage);
212 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
213 ApiMessage.h.u2.ZeroInit = 0;
214
215 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength = PackageName->Length;
216 strncpy(ApiMessage.LookupAuthenticationPackage.Request.PackageName,
217 PackageName->Buffer,
218 ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength);
219 ApiMessage.LookupAuthenticationPackage.Request.PackageName[ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength] = '\0';
220
221 Status = ZwRequestWaitReplyPort(LsaHandle,
222 (PPORT_MESSAGE)&ApiMessage,
223 (PPORT_MESSAGE)&ApiMessage);
224 if (!NT_SUCCESS(Status))
225 {
226 return Status;
227 }
228
229 if (!NT_SUCCESS(ApiMessage.Status))
230 {
231 return ApiMessage.Status;
232 }
233
234 *AuthenticationPackage = ApiMessage.LookupAuthenticationPackage.Reply.Package;
235
236 return Status;
237 }
238
239
240 /*
241 * @implemented
242 */
243 NTSTATUS WINAPI
244 LsaLogonUser(HANDLE LsaHandle,
245 PLSA_STRING OriginName,
246 SECURITY_LOGON_TYPE LogonType,
247 ULONG AuthenticationPackage,
248 PVOID AuthenticationInformation,
249 ULONG AuthenticationInformationLength,
250 PTOKEN_GROUPS LocalGroups,
251 PTOKEN_SOURCE SourceContext,
252 PVOID *ProfileBuffer,
253 PULONG ProfileBufferLength,
254 PLUID LogonId,
255 PHANDLE Token,
256 PQUOTA_LIMITS Quotas,
257 PNTSTATUS SubStatus)
258 {
259 LSA_API_MSG ApiMessage;
260 NTSTATUS Status;
261
262 ApiMessage.ApiNumber = LSASS_REQUEST_LOGON_USER;
263 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LogonUser);
264 ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
265 ApiMessage.h.u2.ZeroInit = 0;
266
267 ApiMessage.LogonUser.Request.OriginName = *OriginName;
268 ApiMessage.LogonUser.Request.LogonType = LogonType;
269 ApiMessage.LogonUser.Request.AuthenticationPackage = AuthenticationPackage;
270 ApiMessage.LogonUser.Request.AuthenticationInformation = AuthenticationInformation;
271 ApiMessage.LogonUser.Request.AuthenticationInformationLength = AuthenticationInformationLength;
272 ApiMessage.LogonUser.Request.LocalGroups = LocalGroups;
273 if (LocalGroups != NULL)
274 ApiMessage.LogonUser.Request.LocalGroupsCount = LocalGroups->GroupCount;
275 else
276 ApiMessage.LogonUser.Request.LocalGroupsCount = 0;
277 ApiMessage.LogonUser.Request.SourceContext = *SourceContext;
278
279 Status = ZwRequestWaitReplyPort(LsaHandle,
280 (PPORT_MESSAGE)&ApiMessage,
281 (PPORT_MESSAGE)&ApiMessage);
282 if (!NT_SUCCESS(Status))
283 {
284 return Status;
285 }
286
287 if (!NT_SUCCESS(ApiMessage.Status))
288 {
289 return ApiMessage.Status;
290 }
291
292 *ProfileBuffer = ApiMessage.LogonUser.Reply.ProfileBuffer;
293 *ProfileBufferLength = ApiMessage.LogonUser.Reply.ProfileBufferLength;
294 *LogonId = ApiMessage.LogonUser.Reply.LogonId;
295 *Token = ApiMessage.LogonUser.Reply.Token;
296 *Quotas = ApiMessage.LogonUser.Reply.Quotas;
297 *SubStatus = ApiMessage.LogonUser.Reply.SubStatus;
298
299 return Status;
300
301 #if 0
302 ULONG RequestLength;
303 ULONG CurrentLength;
304 PLSASS_REQUEST Request;
305 LSASS_REQUEST RawMessage;
306 PLSASS_REPLY Reply;
307 LSASS_REPLY RawReply;
308 NTSTATUS Status;
309
310 RequestLength = sizeof(LSASS_REQUEST) - sizeof(PORT_MESSAGE);
311 RequestLength = RequestLength + (OriginName->Length * sizeof(WCHAR));
312 RequestLength = RequestLength + AuthenticationInformationLength;
313 RequestLength = RequestLength +
314 (LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES));
315
316 CurrentLength = 0;
317 Request = (PLSASS_REQUEST)&RawMessage;
318
319 Request->d.LogonUserRequest.OriginNameLength = OriginName->Length;
320 Request->d.LogonUserRequest.OriginName = (PWSTR)&RawMessage + CurrentLength;
321 memcpy((PWSTR)&RawMessage + CurrentLength,
322 OriginName->Buffer,
323 OriginName->Length * sizeof(WCHAR));
324 CurrentLength = CurrentLength + (OriginName->Length * sizeof(WCHAR));
325
326 Request->d.LogonUserRequest.LogonType = LogonType;
327
328 Request->d.LogonUserRequest.AuthenticationPackage =
329 AuthenticationPackage;
330
331 Request->d.LogonUserRequest.AuthenticationInformation =
332 (PVOID)((ULONG_PTR)&RawMessage + CurrentLength);
333 Request->d.LogonUserRequest.AuthenticationInformationLength =
334 AuthenticationInformationLength;
335 memcpy((PVOID)((ULONG_PTR)&RawMessage + CurrentLength),
336 AuthenticationInformation,
337 AuthenticationInformationLength);
338 CurrentLength = CurrentLength + AuthenticationInformationLength;
339
340 Request->d.LogonUserRequest.LocalGroupsCount = LocalGroups->GroupCount;
341 Request->d.LogonUserRequest.LocalGroups =
342 (PSID_AND_ATTRIBUTES)&RawMessage + CurrentLength;
343 memcpy((PSID_AND_ATTRIBUTES)&RawMessage + CurrentLength,
344 LocalGroups->Groups,
345 LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES));
346
347 Request->d.LogonUserRequest.SourceContext = *SourceContext;
348
349 Request->Type = LSASS_REQUEST_LOGON_USER;
350 Request->Header.u1.s1.DataLength = RequestLength - sizeof(PORT_MESSAGE);
351 Request->Header.u1.s1.TotalLength = RequestLength + sizeof(PORT_MESSAGE);
352
353 Reply = (PLSASS_REPLY)&RawReply;
354
355 Status = ZwRequestWaitReplyPort(LsaHandle,
356 &Request->Header,
357 &Reply->Header);
358 if (!NT_SUCCESS(Status))
359 {
360 return Status;
361 }
362
363 *SubStatus = Reply->d.LogonUserReply.SubStatus;
364
365 if (!NT_SUCCESS(Reply->Status))
366 {
367 return Status;
368 }
369
370 *ProfileBuffer = RtlAllocateHeap(Secur32Heap,
371 0,
372 Reply->d.LogonUserReply.ProfileBufferLength);
373 memcpy(*ProfileBuffer,
374 (PVOID)((ULONG_PTR)Reply->d.LogonUserReply.Data +
375 (ULONG_PTR)Reply->d.LogonUserReply.ProfileBuffer),
376 Reply->d.LogonUserReply.ProfileBufferLength);
377 *LogonId = Reply->d.LogonUserReply.LogonId;
378 *Token = Reply->d.LogonUserReply.Token;
379 memcpy(Quotas,
380 &Reply->d.LogonUserReply.Quotas,
381 sizeof(Reply->d.LogonUserReply.Quotas));
382
383 return Status;
384 #endif
385 }
386
387
388 /*
389 * @implemented
390 */
391 NTSTATUS WINAPI
392 LsaRegisterLogonProcess(PLSA_STRING LsaLogonProcessName,
393 PHANDLE Handle,
394 PLSA_OPERATIONAL_MODE OperationalMode)
395 {
396 UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
397 SECURITY_QUALITY_OF_SERVICE SecurityQos;
398 LSA_CONNECTION_INFO ConnectInfo;
399 ULONG ConnectInfoLength = sizeof(ConnectInfo);
400 NTSTATUS Status;
401
402 DPRINT1("LsaRegisterLogonProcess()\n");
403
404 /* Check the logon process name length */
405 if (LsaLogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH)
406 return STATUS_NAME_TOO_LONG;
407
408 RtlInitUnicodeString(&PortName,
409 L"\\LsaAuthenticationPort");
410
411 SecurityQos.Length = sizeof(SecurityQos);
412 SecurityQos.ImpersonationLevel = SecurityIdentification;
413 SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
414 SecurityQos.EffectiveOnly = TRUE;
415
416 strncpy(ConnectInfo.LogonProcessNameBuffer,
417 LsaLogonProcessName->Buffer,
418 LsaLogonProcessName->Length);
419 ConnectInfo.Length = LsaLogonProcessName->Length;
420 ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = '\0';
421
422 Status = ZwConnectPort(Handle,
423 &PortName,
424 &SecurityQos,
425 NULL,
426 NULL,
427 NULL,
428 &ConnectInfo,
429 &ConnectInfoLength);
430 if (!NT_SUCCESS(Status))
431 {
432 DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status);
433 return Status;
434 }
435
436 DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo.OperationalMode);
437 *OperationalMode = ConnectInfo.OperationalMode;
438
439 if (!NT_SUCCESS(Status))
440 {
441 DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
442 }
443
444 return ConnectInfo.Status;
445 }
446
447
448 /*
449 * @unimplemented
450 */
451 NTSTATUS
452 WINAPI
453 LsaEnumerateLogonSessions(PULONG LogonSessionCount,
454 PLUID *LogonSessionList)
455 {
456 UNIMPLEMENTED;
457 return STATUS_NOT_IMPLEMENTED;
458 }
459
460
461 /*
462 * @unimplemented
463 */
464 NTSTATUS
465 WINAPI
466 LsaGetLogonSessionData(PLUID LogonId,
467 PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData)
468 {
469 UNIMPLEMENTED;
470 return STATUS_NOT_IMPLEMENTED;
471 }
472
473
474 /*
475 * @unimplemented
476 */
477 NTSTATUS
478 WINAPI
479 LsaRegisterPolicyChangeNotification(POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
480 HANDLE NotificationEventHandle)
481 {
482 UNIMPLEMENTED;
483 return STATUS_NOT_IMPLEMENTED;
484 }
485
486
487 /*
488 * @unimplemented
489 */
490 NTSTATUS
491 WINAPI
492 LsaUnregisterPolicyChangeNotification(POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
493 HANDLE NotificationEventHandle)
494 {
495 UNIMPLEMENTED;
496 return STATUS_NOT_IMPLEMENTED;
497 }