wined3d: Implement multisample resolve for typed resources.
[wine.git] / dlls / secur32 / lsa.c
blobb93006a24f96df5adf9f11b5a61fb0e902bd0e5b
1 /*
2 * Copyright (C) 2004 Juan Lang
3 * Copyright (C) 2007 Kai Blin
4 * Copyright (C) 2017, 2018 Dmitry Timoshkov
6 * Local Security Authority functions, as far as secur32 has them.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdarg.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winreg.h"
30 #include "sspi.h"
31 #include "ntsecapi.h"
32 #include "ntsecpkg.h"
33 #include "winternl.h"
34 #include "rpc.h"
35 #include "secur32_priv.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
41 #define LSA_MAGIC ('L' << 24 | 'S' << 16 | 'A' << 8 | ' ')
43 struct lsa_package
45 ULONG package_id;
46 HMODULE mod;
47 LSA_STRING *name;
48 ULONG lsa_api_version, lsa_table_count, user_api_version, user_table_count;
49 SECPKG_FUNCTION_TABLE *lsa_api;
50 SECPKG_USER_FUNCTION_TABLE *user_api;
53 static struct lsa_package *loaded_packages;
54 static ULONG loaded_packages_count;
56 struct lsa_connection
58 DWORD magic;
61 static const char *debugstr_as(const LSA_STRING *str)
63 if (!str) return "<null>";
64 return debugstr_an(str->Buffer, str->Length);
67 NTSTATUS WINAPI LsaCallAuthenticationPackage(HANDLE lsa_handle, ULONG package_id,
68 PVOID in_buffer, ULONG in_buffer_length,
69 PVOID *out_buffer, PULONG out_buffer_length, PNTSTATUS status)
71 ULONG i;
73 TRACE("%p,%u,%p,%u,%p,%p,%p\n", lsa_handle, package_id, in_buffer,
74 in_buffer_length, out_buffer, out_buffer_length, status);
76 for (i = 0; i < loaded_packages_count; i++)
78 if (loaded_packages[i].package_id == package_id)
80 if (loaded_packages[i].lsa_api->CallPackageUntrusted)
81 return loaded_packages[i].lsa_api->CallPackageUntrusted(NULL /* FIXME*/,
82 in_buffer, NULL, in_buffer_length, out_buffer, out_buffer_length, status);
84 return SEC_E_UNSUPPORTED_FUNCTION;
88 return STATUS_INVALID_PARAMETER;
91 NTSTATUS WINAPI LsaConnectUntrusted(PHANDLE LsaHandle)
93 struct lsa_connection *lsa_conn;
95 TRACE("%p\n", LsaHandle);
97 lsa_conn = HeapAlloc(GetProcessHeap(), 0, sizeof(*lsa_conn));
98 if (!lsa_conn) return STATUS_NO_MEMORY;
100 lsa_conn->magic = LSA_MAGIC;
101 *LsaHandle = lsa_conn;
103 return STATUS_SUCCESS;
106 NTSTATUS WINAPI LsaDeregisterLogonProcess(HANDLE LsaHandle)
108 FIXME("%p stub\n", LsaHandle);
109 return STATUS_SUCCESS;
112 NTSTATUS WINAPI LsaEnumerateLogonSessions(PULONG LogonSessionCount,
113 PLUID* LogonSessionList)
115 FIXME("%p %p stub\n", LogonSessionCount, LogonSessionList);
116 *LogonSessionCount = 0;
117 *LogonSessionList = NULL;
119 return STATUS_SUCCESS;
122 NTSTATUS WINAPI LsaFreeReturnBuffer(PVOID buffer)
124 TRACE("%p\n", buffer);
125 HeapFree(GetProcessHeap(), 0, buffer);
126 return STATUS_SUCCESS;
129 NTSTATUS WINAPI LsaGetLogonSessionData(PLUID LogonId,
130 PSECURITY_LOGON_SESSION_DATA* ppLogonSessionData)
132 FIXME("%p %p stub\n", LogonId, ppLogonSessionData);
133 *ppLogonSessionData = NULL;
134 return STATUS_NOT_IMPLEMENTED;
137 NTSTATUS WINAPI LsaLogonUser(HANDLE LsaHandle, PLSA_STRING OriginName,
138 SECURITY_LOGON_TYPE LogonType, ULONG AuthenticationPackage,
139 PVOID AuthenticationInformation, ULONG AuthenticationInformationLength,
140 PTOKEN_GROUPS LocalGroups, PTOKEN_SOURCE SourceContext,
141 PVOID* ProfileBuffer, PULONG ProfileBufferLength, PLUID LogonId,
142 PHANDLE Token, PQUOTA_LIMITS Quotas, PNTSTATUS SubStatus)
144 FIXME("%p %s %d %d %p %d %p %p %p %p %p %p %p %p stub\n", LsaHandle,
145 debugstr_as(OriginName), LogonType, AuthenticationPackage,
146 AuthenticationInformation, AuthenticationInformationLength,
147 LocalGroups, SourceContext, ProfileBuffer, ProfileBufferLength,
148 LogonId, Token, Quotas, SubStatus);
149 return STATUS_SUCCESS;
152 static NTSTATUS NTAPI lsa_CreateLogonSession(LUID *logon_id)
154 FIXME("%p: stub\n", logon_id);
155 return STATUS_NOT_IMPLEMENTED;
158 static NTSTATUS NTAPI lsa_DeleteLogonSession(LUID *logon_id)
160 FIXME("%p: stub\n", logon_id);
161 return STATUS_NOT_IMPLEMENTED;
164 static NTSTATUS NTAPI lsa_AddCredential(LUID *logon_id, ULONG package_id,
165 LSA_STRING *primary_key, LSA_STRING *credentials)
167 FIXME("%p,%u,%s,%s: stub\n", logon_id, package_id,
168 debugstr_as(primary_key), debugstr_as(credentials));
169 return STATUS_NOT_IMPLEMENTED;
172 static NTSTATUS NTAPI lsa_GetCredentials(LUID *logon_id, ULONG package_id, ULONG *context,
173 BOOLEAN retrieve_all, LSA_STRING *primary_key, ULONG *primary_key_len, LSA_STRING *credentials)
175 FIXME("%p,%#x,%p,%d,%p,%p,%p: stub\n", logon_id, package_id, context,
176 retrieve_all, primary_key, primary_key_len, credentials);
177 return STATUS_NOT_IMPLEMENTED;
180 static NTSTATUS NTAPI lsa_DeleteCredential(LUID *logon_id, ULONG package_id, LSA_STRING *primary_key)
182 FIXME("%p,%#x,%s: stub\n", logon_id, package_id, debugstr_as(primary_key));
183 return STATUS_NOT_IMPLEMENTED;
186 static void * NTAPI lsa_AllocateLsaHeap(ULONG size)
188 TRACE("%u\n", size);
189 return HeapAlloc(GetProcessHeap(), 0, size);
192 static void NTAPI lsa_FreeLsaHeap(void *p)
194 TRACE("%p\n", p);
195 HeapFree(GetProcessHeap(), 0, p);
198 static NTSTATUS NTAPI lsa_AllocateClientBuffer(PLSA_CLIENT_REQUEST req, ULONG size, void **p)
200 TRACE("%p,%u,%p\n", req, size, p);
201 *p = HeapAlloc(GetProcessHeap(), 0, size);
202 return *p ? STATUS_SUCCESS : STATUS_NO_MEMORY;
205 static NTSTATUS NTAPI lsa_FreeClientBuffer(PLSA_CLIENT_REQUEST req, void *p)
207 TRACE("%p,%p\n", req, p);
208 HeapFree(GetProcessHeap(), 0, p);
209 return STATUS_SUCCESS;
212 static NTSTATUS NTAPI lsa_CopyToClientBuffer(PLSA_CLIENT_REQUEST req, ULONG size, void *client, void *buf)
214 TRACE("%p,%u,%p,%p\n", req, size, client, buf);
215 memcpy(client, buf, size);
216 return STATUS_SUCCESS;
219 static NTSTATUS NTAPI lsa_CopyFromClientBuffer(PLSA_CLIENT_REQUEST req, ULONG size, void *buf, void *client)
221 TRACE("%p,%u,%p,%p\n", req, size, buf, client);
222 memcpy(buf, client, size);
223 return STATUS_SUCCESS;
226 static LSA_DISPATCH_TABLE lsa_dispatch =
228 lsa_CreateLogonSession,
229 lsa_DeleteLogonSession,
230 lsa_AddCredential,
231 lsa_GetCredentials,
232 lsa_DeleteCredential,
233 lsa_AllocateLsaHeap,
234 lsa_FreeLsaHeap,
235 lsa_AllocateClientBuffer,
236 lsa_FreeClientBuffer,
237 lsa_CopyToClientBuffer,
238 lsa_CopyFromClientBuffer
241 static NTSTATUS NTAPI lsa_RegisterCallback(ULONG callback_id, PLSA_CALLBACK_FUNCTION callback)
243 FIXME("%u,%p: stub\n", callback_id, callback);
244 return STATUS_NOT_IMPLEMENTED;
247 static SECPKG_DLL_FUNCTIONS lsa_dll_dispatch =
249 lsa_AllocateLsaHeap,
250 lsa_FreeLsaHeap,
251 lsa_RegisterCallback
254 static SECURITY_STATUS lsa_lookup_package(SEC_WCHAR *nameW, struct lsa_package **lsa_package)
256 ULONG i;
257 UNICODE_STRING package_name, name;
259 for (i = 0; i < loaded_packages_count; i++)
261 if (RtlAnsiStringToUnicodeString(&package_name, loaded_packages[i].name, TRUE))
262 return SEC_E_INSUFFICIENT_MEMORY;
264 RtlInitUnicodeString(&name, nameW);
266 if (RtlEqualUnicodeString(&package_name, &name, TRUE))
268 RtlFreeUnicodeString(&package_name);
269 *lsa_package = &loaded_packages[i];
270 return SEC_E_OK;
273 RtlFreeUnicodeString(&package_name);
276 return SEC_E_SECPKG_NOT_FOUND;
279 static SECURITY_STATUS WINAPI lsa_AcquireCredentialsHandleW(
280 SEC_WCHAR *principal, SEC_WCHAR *package, ULONG credentials_use,
281 LUID *logon_id, void *auth_data, SEC_GET_KEY_FN get_key_fn,
282 void *get_key_arg, CredHandle *credential, TimeStamp *ts_expiry)
284 SECURITY_STATUS status;
285 struct lsa_package *lsa_package;
286 UNICODE_STRING principal_us;
287 LSA_SEC_HANDLE lsa_credential;
289 TRACE("%s %s %#x %p %p %p %p %p\n", debugstr_w(principal), debugstr_w(package),
290 credentials_use, auth_data, get_key_fn, get_key_arg, credential, ts_expiry);
292 if (!credential) return SEC_E_INVALID_HANDLE;
293 if (!package) return SEC_E_SECPKG_NOT_FOUND;
295 status = lsa_lookup_package(package, &lsa_package);
296 if (status != SEC_E_OK) return status;
298 if (!lsa_package->lsa_api || !lsa_package->lsa_api->SpAcquireCredentialsHandle)
299 return SEC_E_UNSUPPORTED_FUNCTION;
301 if (principal)
302 RtlInitUnicodeString(&principal_us, principal);
304 status = lsa_package->lsa_api->SpAcquireCredentialsHandle(principal ? &principal_us : NULL,
305 credentials_use, logon_id, auth_data, get_key_fn, get_key_arg, &lsa_credential, ts_expiry);
306 if (status == SEC_E_OK)
308 credential->dwLower = (ULONG_PTR)lsa_credential;
309 credential->dwUpper = (ULONG_PTR)lsa_package;
311 return status;
314 static SECURITY_STATUS WINAPI lsa_AcquireCredentialsHandleA(
315 SEC_CHAR *principal, SEC_CHAR *package, ULONG credentials_use,
316 LUID *logon_id, void *auth_data, SEC_GET_KEY_FN get_key_fn,
317 void *get_key_arg, CredHandle *credential, TimeStamp *ts_expiry)
319 SECURITY_STATUS status = SEC_E_INSUFFICIENT_MEMORY;
320 int len_user = 0, len_domain = 0, len_passwd = 0;
321 SEC_WCHAR *principalW = NULL, *packageW = NULL, *user = NULL, *domain = NULL, *passwd = NULL;
322 SEC_WINNT_AUTH_IDENTITY_W *auth_dataW = NULL;
323 SEC_WINNT_AUTH_IDENTITY_A *id = NULL;
325 TRACE("%s %s %#x %p %p %p %p %p\n", debugstr_a(principal), debugstr_a(package),
326 credentials_use, auth_data, get_key_fn, get_key_arg, credential, ts_expiry);
328 if (principal)
330 int len = MultiByteToWideChar( CP_ACP, 0, principal, -1, NULL, 0 );
331 if (!(principalW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(SEC_WCHAR) ))) goto done;
332 MultiByteToWideChar( CP_ACP, 0, principal, -1, principalW, len );
334 if (package)
336 int len = MultiByteToWideChar( CP_ACP, 0, package, -1, NULL, 0 );
337 if (!(packageW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(SEC_WCHAR) ))) goto done;
338 MultiByteToWideChar( CP_ACP, 0, package, -1, packageW, len );
340 if (auth_data)
342 id = (PSEC_WINNT_AUTH_IDENTITY_A)auth_data;
344 if (id->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
346 if (!(auth_dataW = HeapAlloc( GetProcessHeap(), 0, sizeof(SEC_WINNT_AUTH_IDENTITY_W) ))) goto done;
347 if (id->UserLength)
349 len_user = MultiByteToWideChar( CP_ACP, 0, (char *)id->User, id->UserLength, NULL, 0 );
350 if (!(user = HeapAlloc( GetProcessHeap(), 0, len_user * sizeof(SEC_WCHAR) ))) goto done;
351 MultiByteToWideChar( CP_ACP, 0, (char *)id->User, id->UserLength, user, len_user );
353 if (id->DomainLength)
355 len_domain = MultiByteToWideChar( CP_ACP, 0, (char *)id->Domain, id->DomainLength, NULL, 0 );
356 if (!(domain = HeapAlloc( GetProcessHeap(), 0, len_domain * sizeof(SEC_WCHAR) ))) goto done;
357 MultiByteToWideChar( CP_ACP, 0, (char *)id->Domain, id->DomainLength, domain, len_domain );
359 if (id->PasswordLength)
361 len_passwd = MultiByteToWideChar( CP_ACP, 0, (char *)id->Password, id->PasswordLength, NULL, 0 );
362 if (!(passwd = HeapAlloc( GetProcessHeap(), 0, len_passwd * sizeof(SEC_WCHAR) ))) goto done;
363 MultiByteToWideChar( CP_ACP, 0, (char *)id->Password, id->PasswordLength, passwd, len_passwd );
365 auth_dataW->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
366 auth_dataW->User = user;
367 auth_dataW->UserLength = len_user;
368 auth_dataW->Domain = domain;
369 auth_dataW->DomainLength = len_domain;
370 auth_dataW->Password = passwd;
371 auth_dataW->PasswordLength = len_passwd;
373 else auth_dataW = (PSEC_WINNT_AUTH_IDENTITY_W)auth_data;
376 status = lsa_AcquireCredentialsHandleW( principalW, packageW, credentials_use, logon_id, auth_dataW, get_key_fn,
377 get_key_arg, credential, ts_expiry );
378 done:
379 if (auth_dataW != (SEC_WINNT_AUTH_IDENTITY_W *)id) HeapFree( GetProcessHeap(), 0, auth_dataW );
380 HeapFree( GetProcessHeap(), 0, packageW );
381 HeapFree( GetProcessHeap(), 0, principalW );
382 HeapFree( GetProcessHeap(), 0, user );
383 HeapFree( GetProcessHeap(), 0, domain );
384 HeapFree( GetProcessHeap(), 0, passwd );
385 return status;
388 static SECURITY_STATUS WINAPI lsa_FreeCredentialsHandle(CredHandle *credential)
390 struct lsa_package *lsa_package;
391 LSA_SEC_HANDLE lsa_credential;
393 TRACE("%p\n", credential);
394 if (!credential) return SEC_E_INVALID_HANDLE;
396 lsa_package = (struct lsa_package *)credential->dwUpper;
397 lsa_credential = (LSA_SEC_HANDLE)credential->dwLower;
399 if (!lsa_package) return SEC_E_INVALID_HANDLE;
401 if (!lsa_package->lsa_api || !lsa_package->lsa_api->FreeCredentialsHandle)
402 return SEC_E_UNSUPPORTED_FUNCTION;
404 return lsa_package->lsa_api->FreeCredentialsHandle(lsa_credential);
407 static SECURITY_STATUS WINAPI lsa_InitializeSecurityContextW(
408 CredHandle *credential, CtxtHandle *context, SEC_WCHAR *target_name, ULONG context_req,
409 ULONG reserved1, ULONG target_data_rep, SecBufferDesc *input, ULONG reserved2,
410 CtxtHandle *new_context, SecBufferDesc *output, ULONG *context_attr, TimeStamp *ts_expiry)
412 SECURITY_STATUS status;
413 struct lsa_package *lsa_package = NULL;
414 LSA_SEC_HANDLE lsa_credential = 0, lsa_context = 0, new_lsa_context;
415 UNICODE_STRING target_name_us;
416 BOOLEAN mapped_context;
418 TRACE("%p %p %s %#x %d %d %p %d %p %p %p %p\n", credential, context,
419 debugstr_w(target_name), context_req, reserved1, target_data_rep, input,
420 reserved2, new_context, output, context_attr, ts_expiry);
422 if (context)
424 lsa_package = (struct lsa_package *)context->dwUpper;
425 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
427 else if (credential)
429 lsa_package = (struct lsa_package *)credential->dwUpper;
430 lsa_credential = (LSA_SEC_HANDLE)credential->dwLower;
433 if (!lsa_package || !new_context) return SEC_E_INVALID_HANDLE;
435 if (!lsa_package->lsa_api || !lsa_package->lsa_api->InitLsaModeContext)
436 return SEC_E_UNSUPPORTED_FUNCTION;
438 if (target_name)
439 RtlInitUnicodeString(&target_name_us, target_name);
441 status = lsa_package->lsa_api->InitLsaModeContext(lsa_credential, lsa_context,
442 target_name ? &target_name_us : NULL, context_req, target_data_rep, input,
443 &new_lsa_context, output, context_attr, ts_expiry, &mapped_context, NULL /* FIXME */);
444 if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED)
446 new_context->dwLower = (ULONG_PTR)new_lsa_context;
447 new_context->dwUpper = (ULONG_PTR)lsa_package;
449 return status;
452 static SECURITY_STATUS WINAPI lsa_InitializeSecurityContextA(
453 CredHandle *credential, CtxtHandle *context, SEC_CHAR *target_name, ULONG context_req,
454 ULONG reserved1, ULONG target_data_rep, SecBufferDesc *input, ULONG reserved2,
455 CtxtHandle *new_context, SecBufferDesc *output, ULONG *context_attr, TimeStamp *ts_expiry)
457 SECURITY_STATUS status;
458 SEC_WCHAR *targetW = NULL;
460 TRACE("%p %p %s %#x %d %d %p %d %p %p %p %p\n", credential, context,
461 debugstr_a(target_name), context_req, reserved1, target_data_rep, input,
462 reserved2, new_context, output, context_attr, ts_expiry);
464 if (target_name)
466 int len = MultiByteToWideChar( CP_ACP, 0, target_name, -1, NULL, 0 );
467 if (!(targetW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY;
468 MultiByteToWideChar( CP_ACP, 0, target_name, -1, targetW, len );
471 status = lsa_InitializeSecurityContextW( credential, context, targetW, context_req, reserved1, target_data_rep,
472 input, reserved2, new_context, output, context_attr, ts_expiry );
473 HeapFree( GetProcessHeap(), 0, targetW );
474 return status;
477 static SECURITY_STATUS WINAPI lsa_AcceptSecurityContext(
478 CredHandle *credential, CtxtHandle *context, SecBufferDesc *input,
479 ULONG context_req, ULONG target_data_rep, CtxtHandle *new_context,
480 SecBufferDesc *output, ULONG *context_attr, TimeStamp *ts_expiry)
482 SECURITY_STATUS status;
483 struct lsa_package *lsa_package = NULL;
484 LSA_SEC_HANDLE lsa_credential = 0, lsa_context = 0, new_lsa_context;
485 BOOLEAN mapped_context;
487 TRACE("%p %p %p %#x %#x %p %p %p %p\n", credential, context, input,
488 context_req, target_data_rep, new_context, output, context_attr, ts_expiry);
490 if (context)
492 lsa_package = (struct lsa_package *)context->dwUpper;
493 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
495 else if (credential)
497 lsa_package = (struct lsa_package *)credential->dwUpper;
498 lsa_credential = (LSA_SEC_HANDLE)credential->dwLower;
501 if (!lsa_package || !new_context) return SEC_E_INVALID_HANDLE;
503 if (!lsa_package->lsa_api || !lsa_package->lsa_api->AcceptLsaModeContext)
504 return SEC_E_UNSUPPORTED_FUNCTION;
506 status = lsa_package->lsa_api->AcceptLsaModeContext(lsa_credential, lsa_context,
507 input, context_req, target_data_rep, &new_lsa_context, output, context_attr,
508 ts_expiry, &mapped_context, NULL /* FIXME */);
509 if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED)
511 new_context->dwLower = (ULONG_PTR)new_lsa_context;
512 new_context->dwUpper = (ULONG_PTR)lsa_package;
514 return status;
517 static SECURITY_STATUS WINAPI lsa_DeleteSecurityContext(CtxtHandle *context)
519 struct lsa_package *lsa_package;
520 LSA_SEC_HANDLE lsa_context;
522 TRACE("%p\n", context);
524 if (!context) return SEC_E_INVALID_HANDLE;
526 lsa_package = (struct lsa_package *)context->dwUpper;
527 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
529 if (!lsa_package) return SEC_E_INVALID_HANDLE;
531 if (!lsa_package->lsa_api || !lsa_package->lsa_api->DeleteContext)
532 return SEC_E_UNSUPPORTED_FUNCTION;
534 return lsa_package->lsa_api->DeleteContext(lsa_context);
537 static SECURITY_STATUS WINAPI lsa_QueryContextAttributesW(CtxtHandle *context, ULONG attribute, void *buffer)
539 struct lsa_package *lsa_package;
540 LSA_SEC_HANDLE lsa_context;
542 TRACE("%p %d %p\n", context, attribute, buffer);
544 if (!context) return SEC_E_INVALID_HANDLE;
546 lsa_package = (struct lsa_package *)context->dwUpper;
547 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
549 if (!lsa_package) return SEC_E_INVALID_HANDLE;
551 if (!lsa_package->lsa_api || !lsa_package->lsa_api->SpQueryContextAttributes)
552 return SEC_E_UNSUPPORTED_FUNCTION;
554 return lsa_package->lsa_api->SpQueryContextAttributes(lsa_context, attribute, buffer);
557 static SecPkgInfoA *package_infoWtoA( const SecPkgInfoW *info )
559 SecPkgInfoA *ret;
560 int size_name = WideCharToMultiByte( CP_ACP, 0, info->Name, -1, NULL, 0, NULL, NULL );
561 int size_comment = WideCharToMultiByte( CP_ACP, 0, info->Comment, -1, NULL, 0, NULL, NULL );
563 if (!(ret = HeapAlloc( GetProcessHeap(), 0, sizeof(*ret) + size_name + size_comment ))) return NULL;
564 ret->fCapabilities = info->fCapabilities;
565 ret->wVersion = info->wVersion;
566 ret->wRPCID = info->wRPCID;
567 ret->cbMaxToken = info->cbMaxToken;
568 ret->Name = (SEC_CHAR *)(ret + 1);
569 WideCharToMultiByte( CP_ACP, 0, info->Name, -1, ret->Name, size_name, NULL, NULL );
570 ret->Comment = ret->Name + size_name;
571 WideCharToMultiByte( CP_ACP, 0, info->Comment, -1, ret->Comment, size_comment, NULL, NULL );
572 return ret;
575 static SECURITY_STATUS nego_info_WtoA( const SecPkgContext_NegotiationInfoW *infoW,
576 SecPkgContext_NegotiationInfoA *infoA )
578 infoA->NegotiationState = infoW->NegotiationState;
579 if (!(infoA->PackageInfo = package_infoWtoA( infoW->PackageInfo ))) return SEC_E_INSUFFICIENT_MEMORY;
580 return SEC_E_OK;
583 static SECURITY_STATUS WINAPI lsa_QueryContextAttributesA(CtxtHandle *context, ULONG attribute, void *buffer)
585 TRACE("%p %d %p\n", context, attribute, buffer);
587 if (!context) return SEC_E_INVALID_HANDLE;
589 switch (attribute)
591 case SECPKG_ATTR_SIZES:
592 return lsa_QueryContextAttributesW( context, attribute, buffer );
594 case SECPKG_ATTR_NEGOTIATION_INFO:
596 SecPkgContext_NegotiationInfoW infoW;
597 SecPkgContext_NegotiationInfoA *infoA = (SecPkgContext_NegotiationInfoA *)buffer;
598 SECURITY_STATUS status = lsa_QueryContextAttributesW( context, SECPKG_ATTR_NEGOTIATION_INFO, &infoW );
600 if (status != SEC_E_OK) return status;
601 status = nego_info_WtoA( &infoW, infoA );
602 FreeContextBuffer( infoW.PackageInfo );
603 return status;
606 #define X(x) case (x) : FIXME(#x" stub\n"); break
607 X(SECPKG_ATTR_ACCESS_TOKEN);
608 X(SECPKG_ATTR_AUTHORITY);
609 X(SECPKG_ATTR_DCE_INFO);
610 X(SECPKG_ATTR_KEY_INFO);
611 X(SECPKG_ATTR_LIFESPAN);
612 X(SECPKG_ATTR_NAMES);
613 X(SECPKG_ATTR_NATIVE_NAMES);
614 X(SECPKG_ATTR_PACKAGE_INFO);
615 X(SECPKG_ATTR_PASSWORD_EXPIRY);
616 X(SECPKG_ATTR_SESSION_KEY);
617 X(SECPKG_ATTR_STREAM_SIZES);
618 X(SECPKG_ATTR_TARGET_INFORMATION);
619 #undef X
620 default:
621 FIXME( "unknown attribute %u\n", attribute );
622 break;
625 return SEC_E_UNSUPPORTED_FUNCTION;
628 static SECURITY_STATUS WINAPI lsa_MakeSignature(CtxtHandle *context, ULONG quality_of_protection,
629 SecBufferDesc *message, ULONG message_seq_no)
631 struct lsa_package *lsa_package;
632 LSA_SEC_HANDLE lsa_context;
634 TRACE("%p %#x %p %u)\n", context, quality_of_protection, message, message_seq_no);
636 if (!context) return SEC_E_INVALID_HANDLE;
638 lsa_package = (struct lsa_package *)context->dwUpper;
639 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
641 if (!lsa_package) return SEC_E_INVALID_HANDLE;
643 if (!lsa_package->user_api || !lsa_package->user_api->MakeSignature)
644 return SEC_E_UNSUPPORTED_FUNCTION;
646 return lsa_package->user_api->MakeSignature(lsa_context, quality_of_protection, message, message_seq_no);
649 static SECURITY_STATUS WINAPI lsa_VerifySignature(CtxtHandle *context, SecBufferDesc *message,
650 ULONG message_seq_no, ULONG *quality_of_protection)
652 struct lsa_package *lsa_package;
653 LSA_SEC_HANDLE lsa_context;
655 TRACE("%p %p %u %p)\n", context, message, message_seq_no, quality_of_protection);
657 if (!context) return SEC_E_INVALID_HANDLE;
659 lsa_package = (struct lsa_package *)context->dwUpper;
660 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
662 if (!lsa_package) return SEC_E_INVALID_HANDLE;
664 if (!lsa_package->user_api || !lsa_package->user_api->VerifySignature)
665 return SEC_E_UNSUPPORTED_FUNCTION;
667 return lsa_package->user_api->VerifySignature(lsa_context, message, message_seq_no, quality_of_protection);
670 static SECURITY_STATUS WINAPI lsa_EncryptMessage(CtxtHandle *context, ULONG quality_of_protection,
671 SecBufferDesc *message, ULONG message_seq_no)
673 struct lsa_package *lsa_package;
674 LSA_SEC_HANDLE lsa_context;
676 TRACE("%p %#x %p %u)\n", context, quality_of_protection, message, message_seq_no);
678 if (!context) return SEC_E_INVALID_HANDLE;
680 lsa_package = (struct lsa_package *)context->dwUpper;
681 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
683 if (!lsa_package) return SEC_E_INVALID_HANDLE;
685 if (!lsa_package->user_api || !lsa_package->user_api->SealMessage)
686 return SEC_E_UNSUPPORTED_FUNCTION;
688 return lsa_package->user_api->SealMessage(lsa_context, quality_of_protection, message, message_seq_no);
691 static SECURITY_STATUS WINAPI lsa_DecryptMessage(CtxtHandle *context, SecBufferDesc *message,
692 ULONG message_seq_no, ULONG *quality_of_protection)
694 struct lsa_package *lsa_package;
695 LSA_SEC_HANDLE lsa_context;
697 TRACE("%p %p %u %p)\n", context, message, message_seq_no, quality_of_protection);
699 if (!context) return SEC_E_INVALID_HANDLE;
701 lsa_package = (struct lsa_package *)context->dwUpper;
702 lsa_context = (LSA_SEC_HANDLE)context->dwLower;
704 if (!lsa_package) return SEC_E_INVALID_HANDLE;
706 if (!lsa_package->user_api || !lsa_package->user_api->UnsealMessage)
707 return SEC_E_UNSUPPORTED_FUNCTION;
709 return lsa_package->user_api->UnsealMessage(lsa_context, message, message_seq_no, quality_of_protection);
712 static const SecurityFunctionTableW lsa_sspi_tableW =
715 NULL, /* EnumerateSecurityPackagesW */
716 NULL, /* QueryCredentialsAttributesW */
717 lsa_AcquireCredentialsHandleW,
718 lsa_FreeCredentialsHandle,
719 NULL, /* Reserved2 */
720 lsa_InitializeSecurityContextW,
721 lsa_AcceptSecurityContext,
722 NULL, /* CompleteAuthToken */
723 lsa_DeleteSecurityContext,
724 NULL, /* ApplyControlToken */
725 lsa_QueryContextAttributesW,
726 NULL, /* ImpersonateSecurityContext */
727 NULL, /* RevertSecurityContext */
728 lsa_MakeSignature,
729 lsa_VerifySignature,
730 NULL, /* FreeContextBuffer */
731 NULL, /* QuerySecurityPackageInfoW */
732 NULL, /* Reserved3 */
733 NULL, /* Reserved4 */
734 NULL, /* ExportSecurityContext */
735 NULL, /* ImportSecurityContextW */
736 NULL, /* AddCredentialsW */
737 NULL, /* Reserved8 */
738 NULL, /* QuerySecurityContextToken */
739 lsa_EncryptMessage,
740 lsa_DecryptMessage,
741 NULL, /* SetContextAttributesW */
744 static const SecurityFunctionTableA lsa_sspi_tableA =
747 NULL, /* EnumerateSecurityPackagesA */
748 NULL, /* QueryCredentialsAttributesA */
749 lsa_AcquireCredentialsHandleA,
750 lsa_FreeCredentialsHandle,
751 NULL, /* Reserved2 */
752 lsa_InitializeSecurityContextA,
753 lsa_AcceptSecurityContext,
754 NULL, /* CompleteAuthToken */
755 lsa_DeleteSecurityContext,
756 NULL, /* ApplyControlToken */
757 lsa_QueryContextAttributesA,
758 NULL, /* ImpersonateSecurityContext */
759 NULL, /* RevertSecurityContext */
760 lsa_MakeSignature,
761 lsa_VerifySignature,
762 NULL, /* FreeContextBuffer */
763 NULL, /* QuerySecurityPackageInfoA */
764 NULL, /* Reserved3 */
765 NULL, /* Reserved4 */
766 NULL, /* ExportSecurityContext */
767 NULL, /* ImportSecurityContextA */
768 NULL, /* AddCredentialsA */
769 NULL, /* Reserved8 */
770 NULL, /* QuerySecurityContextToken */
771 lsa_EncryptMessage,
772 lsa_DecryptMessage,
773 NULL, /* SetContextAttributesA */
776 static void add_package(struct lsa_package *package)
778 struct lsa_package *new_loaded_packages;
780 if (!loaded_packages)
781 new_loaded_packages = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_loaded_packages));
782 else
783 new_loaded_packages = HeapReAlloc(GetProcessHeap(), 0, loaded_packages, sizeof(*new_loaded_packages) * (loaded_packages_count + 1));
785 if (new_loaded_packages)
787 loaded_packages = new_loaded_packages;
788 loaded_packages[loaded_packages_count] = *package;
789 loaded_packages_count++;
793 static BOOL load_package(const WCHAR *name, struct lsa_package *package, ULONG package_id)
795 NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG, PSECPKG_FUNCTION_TABLE *, PULONG);
796 NTSTATUS (NTAPI *pSpUserModeInitialize)(ULONG, PULONG, PSECPKG_USER_FUNCTION_TABLE *, PULONG);
798 memset(package, 0, sizeof(*package));
800 package->mod = LoadLibraryW(name);
801 if (!package->mod) return FALSE;
803 pSpLsaModeInitialize = (void *)GetProcAddress(package->mod, "SpLsaModeInitialize");
804 if (pSpLsaModeInitialize)
806 NTSTATUS status;
808 status = pSpLsaModeInitialize(SECPKG_INTERFACE_VERSION, &package->lsa_api_version, &package->lsa_api, &package->lsa_table_count);
809 if (status == STATUS_SUCCESS)
811 status = package->lsa_api->InitializePackage(package_id, &lsa_dispatch, NULL, NULL, &package->name);
812 if (status == STATUS_SUCCESS)
814 TRACE("%s => %p, name %s, version %#x, api table %p, table count %u\n",
815 debugstr_w(name), package->mod, debugstr_an(package->name->Buffer, package->name->Length),
816 package->lsa_api_version, package->lsa_api, package->lsa_table_count);
817 package->package_id = package_id;
819 status = package->lsa_api->Initialize(package_id, NULL /* FIXME: params */, NULL);
820 if (status == STATUS_SUCCESS)
822 pSpUserModeInitialize = (void *)GetProcAddress(package->mod, "SpUserModeInitialize");
823 if (pSpUserModeInitialize)
825 status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &package->user_api_version, &package->user_api, &package->user_table_count);
826 if (status == STATUS_SUCCESS)
827 package->user_api->InstanceInit(SECPKG_INTERFACE_VERSION, &lsa_dll_dispatch, NULL);
830 return TRUE;
835 FreeLibrary(package->mod);
836 return FALSE;
839 #define MAX_SERVICE_NAME 260
841 void load_auth_packages(void)
843 static const WCHAR LSA_KEY[] = { 'S','y','s','t','e','m','\\',
844 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
845 'C','o','n','t','r','o','l','\\','L','s','a',0 };
846 DWORD err, i;
847 HKEY root;
848 SecureProvider *provider;
850 err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, LSA_KEY, 0, KEY_READ, &root);
851 if (err != ERROR_SUCCESS) return;
853 i = 0;
854 for (;;)
856 WCHAR name[MAX_SERVICE_NAME];
857 struct lsa_package package;
859 err = RegEnumKeyW(root, i++, name, MAX_SERVICE_NAME);
860 if (err == ERROR_NO_MORE_ITEMS)
861 break;
863 if (err != ERROR_SUCCESS)
864 continue;
866 if (!load_package(name, &package, i))
867 continue;
869 add_package(&package);
872 RegCloseKey(root);
874 if (!loaded_packages_count) return;
876 provider = SECUR32_addProvider(&lsa_sspi_tableA, &lsa_sspi_tableW, NULL);
877 if (!provider)
879 ERR("Failed to add SSP/AP provider\n");
880 return;
883 for (i = 0; i < loaded_packages_count; i++)
885 SecPkgInfoW *info;
887 info = HeapAlloc(GetProcessHeap(), 0, loaded_packages[i].lsa_table_count * sizeof(*info));
888 if (info)
890 NTSTATUS status;
892 status = loaded_packages[i].lsa_api->GetInfo(info);
893 if (status == STATUS_SUCCESS)
894 SECUR32_addPackages(provider, loaded_packages[i].lsa_table_count, NULL, info);
896 HeapFree(GetProcessHeap(), 0, info);
901 NTSTATUS WINAPI LsaLookupAuthenticationPackage(HANDLE lsa_handle,
902 PLSA_STRING package_name, PULONG package_id)
904 ULONG i;
906 TRACE("%p %s %p\n", lsa_handle, debugstr_as(package_name), package_id);
908 for (i = 0; i < loaded_packages_count; i++)
910 if (!RtlCompareString(loaded_packages[i].name, package_name, FALSE))
912 *package_id = loaded_packages[i].package_id;
913 return STATUS_SUCCESS;
917 return STATUS_UNSUCCESSFUL; /* FIXME */
920 NTSTATUS WINAPI LsaRegisterLogonProcess(PLSA_STRING LogonProcessName,
921 PHANDLE LsaHandle, PLSA_OPERATIONAL_MODE SecurityMode)
923 FIXME("%p %p %p stub\n", LogonProcessName, LsaHandle, SecurityMode);
924 return STATUS_SUCCESS;