[LSASRV]
[reactos.git] / reactos / dll / win32 / lsasrv / authpackage.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/authpackage.c
5 * PURPOSE: Authenticaton package management routines
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 /* INCLUDES ****************************************************************/
10
11 #include "lsasrv.h"
12
13 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
14
15 typedef enum _LSA_TOKEN_INFORMATION_TYPE
16 {
17 LsaTokenInformationNull,
18 LsaTokenInformationV1
19 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
20
21 typedef PVOID PLSA_CLIENT_REQUEST;
22
23 typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG);
24 typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID);
25 typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*);
26 typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID);
27
28 typedef struct LSA_DISPATCH_TABLE
29 {
30 PVOID /*PLSA_CREATE_LOGON_SESSION */ CreateLogonSession;
31 PVOID /*PLSA_DELETE_LOGON_SESSION */ DeleteLogonSession;
32 PVOID /*PLSA_ADD_CREDENTIAL */ AddCredential;
33 PVOID /*PLSA_GET_CREDENTIALS */ GetCredentials;
34 PVOID /*PLSA_DELETE_CREDENTIAL */ DeleteCredential;
35 PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
36 PLSA_FREE_LSA_HEAP FreeLsaHeap;
37 PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
38 PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
39 PVOID /*PLSA_COPY_TO_CLIENT_BUFFER */ CopyToClientBuffer;
40 PVOID /*PLSA_COPY_FROM_CLIENT_BUFFER */ CopyFromClientBuffer;
41 } LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;
42
43
44 typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE,
45 PLSA_STRING, PLSA_STRING, PLSA_STRING *);
46 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_INTERNAL)(PLSA_CLIENT_REQUEST, PVOID, PVOID,
47 ULONG, PVOID *, PULONG, PNTSTATUS);
48 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST,
49 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
50 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PLSA_CLIENT_REQUEST,
51 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
52 typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID);
53 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(PLSA_CLIENT_REQUEST,
54 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
55 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
56 PUNICODE_STRING *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
57 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST,
58 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
59 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
60 PUNICODE_STRING *);
61
62 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_INTERNAL)(PLSA_CLIENT_REQUEST, SECURITY_LOGON_TYPE,
63 PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, PLSA_TOKEN_INFORMATION_TYPE,
64 PVOID *, PUNICODE_STRING *, PUNICODE_STRING *);
65
66 typedef struct _AUTH_PACKAGE
67 {
68 LIST_ENTRY Entry;
69 PSTRING Name;
70 ULONG Id;
71 PVOID ModuleHandle;
72
73 PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage;
74 PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage;
75 PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough;
76 PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted;
77 PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated;
78 PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2;
79 PLSA_AP_LOGON_USER_EX LsaApLogonUserEx;
80 PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
81 } AUTH_PACKAGE, *PAUTH_PACKAGE;
82
83
84 /* GLOBALS *****************************************************************/
85
86 static LIST_ENTRY PackageListHead;
87 static ULONG PackageId;
88 static LSA_DISPATCH_TABLE DispatchTable;
89
90
91 /* FUNCTIONS ***************************************************************/
92
93 static
94 NTSTATUS
95 NTAPI
96 LsapAddAuthPackage(IN PWSTR ValueName,
97 IN ULONG ValueType,
98 IN PVOID ValueData,
99 IN ULONG ValueLength,
100 IN PVOID Context,
101 IN PVOID EntryContext)
102 {
103 PAUTH_PACKAGE Package = NULL;
104 UNICODE_STRING PackageName;
105 STRING ProcName;
106 PULONG Id;
107 NTSTATUS Status = STATUS_SUCCESS;
108
109 TRACE("LsapAddAuthPackage()\n");
110
111 PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR);
112 PackageName.MaximumLength = (USHORT)ValueLength;
113 PackageName.Buffer = ValueData;
114
115 Id = (PULONG)Context;
116
117 Package = RtlAllocateHeap(RtlGetProcessHeap(),
118 HEAP_ZERO_MEMORY,
119 sizeof(AUTH_PACKAGE));
120 if (Package == NULL)
121 return STATUS_INSUFFICIENT_RESOURCES;
122
123 Status = LdrLoadDll(NULL,
124 NULL,
125 &PackageName,
126 &Package->ModuleHandle);
127 if (!NT_SUCCESS(Status))
128 {
129 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status);
130 goto done;
131 }
132
133 RtlInitAnsiString(&ProcName, "LsaApInitializePackage");
134 Status = LdrGetProcedureAddress(Package->ModuleHandle,
135 &ProcName,
136 0,
137 (PVOID *)&Package->LsaApInitializePackage);
138 if (!NT_SUCCESS(Status))
139 {
140 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
141 goto done;
142 }
143
144 RtlInitAnsiString(&ProcName, "LsaApCallPackage");
145 Status = LdrGetProcedureAddress(Package->ModuleHandle,
146 &ProcName,
147 0,
148 (PVOID *)&Package->LsaApCallPackage);
149 if (!NT_SUCCESS(Status))
150 {
151 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
152 goto done;
153 }
154
155 RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough");
156 Status = LdrGetProcedureAddress(Package->ModuleHandle,
157 &ProcName,
158 0,
159 (PVOID *)&Package->LsaApCallPackagePassthrough);
160 if (!NT_SUCCESS(Status))
161 {
162 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
163 goto done;
164 }
165
166 RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted");
167 Status = LdrGetProcedureAddress(Package->ModuleHandle,
168 &ProcName,
169 0,
170 (PVOID *)&Package->LsaApCallPackageUntrusted);
171 if (!NT_SUCCESS(Status))
172 {
173 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
174 goto done;
175 }
176
177 RtlInitAnsiString(&ProcName, "LsaApLogonTerminated");
178 Status = LdrGetProcedureAddress(Package->ModuleHandle,
179 &ProcName,
180 0,
181 (PVOID *)&Package->LsaApLogonTerminated);
182 if (!NT_SUCCESS(Status))
183 {
184 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
185 goto done;
186 }
187
188 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2");
189 Status = LdrGetProcedureAddress(Package->ModuleHandle,
190 &ProcName,
191 0,
192 (PVOID *)&Package->LsaApLogonUserEx2);
193 if (!NT_SUCCESS(Status))
194 {
195 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx");
196 Status = LdrGetProcedureAddress(Package->ModuleHandle,
197 &ProcName,
198 0,
199 (PVOID *)&Package->LsaApLogonUserEx);
200 if (!NT_SUCCESS(Status))
201 {
202 RtlInitAnsiString(&ProcName, "LsaApLogonUser");
203 Status = LdrGetProcedureAddress(Package->ModuleHandle,
204 &ProcName,
205 0,
206 (PVOID *)&Package->LsaApLogonUser);
207 if (!NT_SUCCESS(Status))
208 {
209 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
210 goto done;
211 }
212 }
213 }
214
215 /* Initialize the current package */
216 Status = Package->LsaApInitializePackage(*Id,
217 &DispatchTable,
218 NULL,
219 NULL,
220 &Package->Name);
221 if (!NT_SUCCESS(Status))
222 {
223 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status);
224 goto done;
225 }
226
227 TRACE("Package Name: %s\n", Package->Name->Buffer);
228
229 Package->Id = *Id;
230 *Id++;
231
232 InsertTailList(&PackageListHead, &Package->Entry);
233
234 done:
235 if (!NT_SUCCESS(Status))
236 {
237 if (Package != NULL)
238 {
239 if (Package->ModuleHandle != NULL)
240 LdrUnloadDll(Package->ModuleHandle);
241
242 if (Package->Name != NULL)
243 {
244 if (Package->Name->Buffer != NULL)
245 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer);
246
247 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name);
248 }
249
250 RtlFreeHeap(RtlGetProcessHeap(), 0, Package);
251 }
252 }
253
254 return Status;
255 }
256
257
258 static
259 PAUTH_PACKAGE
260 LsapGetAuthenticationPackage(IN ULONG PackageId)
261 {
262 PLIST_ENTRY ListEntry;
263 PAUTH_PACKAGE Package;
264
265 ListEntry = PackageListHead.Flink;
266 while (ListEntry != &PackageListHead)
267 {
268 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
269
270 if (Package->Id == PackageId)
271 {
272 return Package;
273 }
274
275 ListEntry = ListEntry->Flink;
276 }
277
278 return NULL;
279 }
280
281
282 static
283 PVOID
284 NTAPI
285 LsapAllocateHeap(IN ULONG Length)
286 {
287 return RtlAllocateHeap(RtlGetProcessHeap(),
288 HEAP_ZERO_MEMORY,
289 Length);
290 }
291
292
293 static
294 VOID
295 NTAPI
296 LsapFreeHeap(IN PVOID Base)
297 {
298 RtlFreeHeap(RtlGetProcessHeap(),
299 0,
300 Base);
301 }
302
303
304 static
305 NTSTATUS
306 NTAPI
307 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
308 IN ULONG LengthRequired,
309 OUT PVOID *ClientBaseAddress)
310 {
311 FIXME("() stub\n");
312 return STATUS_NOT_IMPLEMENTED;
313 }
314
315
316 static
317 NTSTATUS
318 NTAPI
319 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
320 IN PVOID ClientBaseAddress)
321 {
322 FIXME("() stub\n");
323 return STATUS_NOT_IMPLEMENTED;
324 }
325
326
327 NTSTATUS
328 LsapInitAuthPackages(VOID)
329 {
330 RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = {
331 {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0},
332 {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}};
333
334 NTSTATUS Status;
335
336 InitializeListHead(&PackageListHead);
337 PackageId = 0;
338
339 /* Initialize the dispatch table */
340 DispatchTable.CreateLogonSession = NULL;
341 DispatchTable.DeleteLogonSession = NULL;
342 DispatchTable.AddCredential = NULL;
343 DispatchTable.GetCredentials = NULL;
344 DispatchTable.DeleteCredential = NULL;
345 DispatchTable.AllocateLsaHeap = &LsapAllocateHeap;
346 DispatchTable.FreeLsaHeap = &LsapFreeHeap;
347 DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
348 DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
349 DispatchTable.CopyToClientBuffer = NULL;
350 DispatchTable.CopyFromClientBuffer = NULL;
351
352 /* Add registered authentication packages */
353 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
354 L"Lsa",
355 AuthPackageTable,
356 &PackageId,
357 NULL);
358
359
360 return STATUS_SUCCESS;
361 }
362
363
364 NTSTATUS
365 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,
366 PLSAP_LOGON_CONTEXT LogonContext)
367 {
368 PLIST_ENTRY ListEntry;
369 PAUTH_PACKAGE Package;
370 ULONG PackageNameLength;
371 PCHAR PackageName;
372
373 TRACE("(%p %p)\n", RequestMsg, LogonContext);
374
375 PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength;
376 PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName;
377
378 TRACE("PackageName: %s\n", PackageName);
379
380 ListEntry = PackageListHead.Flink;
381 while (ListEntry != &PackageListHead)
382 {
383 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
384
385 if ((PackageNameLength == Package->Name->Length) &&
386 (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0))
387 {
388 RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id;
389 return STATUS_SUCCESS;
390 }
391
392 ListEntry = ListEntry->Flink;
393 }
394
395 return STATUS_NO_SUCH_PACKAGE;
396 }
397
398
399 NTSTATUS
400 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
401 PLSAP_LOGON_CONTEXT LogonContext)
402 {
403 PAUTH_PACKAGE Package;
404 ULONG PackageId;
405
406 NTSTATUS Status;
407
408 TRACE("(%p %p)\n", RequestMsg, LogonContext);
409
410 PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
411
412 Package = LsapGetAuthenticationPackage(PackageId);
413 if (Package == NULL)
414 {
415 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
416 return STATUS_NO_SUCH_PACKAGE;
417 }
418
419 Status = Package->LsaApCallPackage(NULL, /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
420 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
421 NULL, /* FIXME: PVOID ClientBufferBase */
422 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
423 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
424 &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
425 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
426 if (!NT_SUCCESS(Status))
427 {
428 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
429 }
430
431 return Status;
432 }
433
434
435 NTSTATUS
436 LsapLogonUser(PLSA_API_MSG RequestMsg,
437 PLSAP_LOGON_CONTEXT LogonContext)
438 {
439 PAUTH_PACKAGE Package;
440 ULONG PackageId;
441 NTSTATUS Status;
442
443 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
444 PVOID TokenInformation = NULL;
445 PUNICODE_STRING AccountName = NULL;
446 PUNICODE_STRING AuthenticatingAuthority = NULL;
447 PUNICODE_STRING MachineName = NULL;
448
449 TRACE("(%p %p)\n", RequestMsg, LogonContext);
450
451 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
452
453 Package = LsapGetAuthenticationPackage(PackageId);
454 if (Package == NULL)
455 {
456 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
457 return STATUS_NO_SUCH_PACKAGE;
458 }
459
460 if (Package->LsaApLogonUserEx2 != NULL)
461 {
462 Status = Package->LsaApLogonUserEx2(NULL, /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
463 RequestMsg->LogonUser.Request.LogonType,
464 RequestMsg->LogonUser.Request.AuthenticationInformation,
465 NULL, /* FIXME: PVOID ClientBufferBase*/
466 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
467 &RequestMsg->LogonUser.Reply.ProfileBuffer,
468 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
469 &RequestMsg->LogonUser.Reply.LogonId,
470 &RequestMsg->LogonUser.Reply.SubStatus,
471 &TokenInformationType,
472 &TokenInformation,
473 &AccountName,
474 &AuthenticatingAuthority,
475 &MachineName,
476 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
477 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
478 }
479 else if (Package->LsaApLogonUserEx != NULL)
480 {
481 Status = Package->LsaApLogonUserEx(NULL, /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
482 RequestMsg->LogonUser.Request.LogonType,
483 RequestMsg->LogonUser.Request.AuthenticationInformation,
484 NULL, /* FIXME: PVOID ClientBufferBase*/
485 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
486 &RequestMsg->LogonUser.Reply.ProfileBuffer,
487 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
488 &RequestMsg->LogonUser.Reply.LogonId,
489 &RequestMsg->LogonUser.Reply.SubStatus,
490 &TokenInformationType,
491 &TokenInformation,
492 &AccountName,
493 &AuthenticatingAuthority,
494 &MachineName);
495 }
496 else
497 {
498 Status = Package->LsaApLogonUser(NULL, /* FIXME: PLSA_CLIENT_REQUEST ClientRequest */
499 RequestMsg->LogonUser.Request.LogonType,
500 RequestMsg->LogonUser.Request.AuthenticationInformation,
501 NULL, /* FIXME: PVOID ClientBufferBase*/
502 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
503 &RequestMsg->LogonUser.Reply.ProfileBuffer,
504 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
505 &RequestMsg->LogonUser.Reply.LogonId,
506 &RequestMsg->LogonUser.Reply.SubStatus,
507 &TokenInformationType,
508 &TokenInformation,
509 &AccountName,
510 &AuthenticatingAuthority);
511 }
512
513
514 if (TokenInformation != NULL)
515 {
516
517 }
518
519 if (AuthenticatingAuthority != NULL)
520 {
521
522 }
523
524 if (AccountName != NULL)
525 {
526
527 }
528
529 if (MachineName != NULL)
530 {
531
532 }
533
534 return Status;
535 }
536
537 /* EOF */