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
26 #define WIN32_NO_STATUS
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 | ' ')
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
;
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
)
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
)
189 return HeapAlloc(GetProcessHeap(), 0, size
);
192 static void NTAPI
lsa_FreeLsaHeap(void *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
,
232 lsa_DeleteCredential
,
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
=
254 static SECURITY_STATUS
lsa_lookup_package(SEC_WCHAR
*nameW
, struct lsa_package
**lsa_package
)
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
];
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
;
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
;
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
);
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
);
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
);
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
;
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
);
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
);
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
);
424 lsa_package
= (struct lsa_package
*)context
->dwUpper
;
425 lsa_context
= (LSA_SEC_HANDLE
)context
->dwLower
;
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
;
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
;
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
);
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
);
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
);
492 lsa_package
= (struct lsa_package
*)context
->dwUpper
;
493 lsa_context
= (LSA_SEC_HANDLE
)context
->dwLower
;
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
;
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
)
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
);
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
;
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
;
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
);
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
);
621 FIXME( "unknown attribute %u\n", attribute
);
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 */
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 */
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 */
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 */
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
));
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
)
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
);
835 FreeLibrary(package
->mod
);
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 };
848 SecureProvider
*provider
;
850 err
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, LSA_KEY
, 0, KEY_READ
, &root
);
851 if (err
!= ERROR_SUCCESS
) return;
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
)
863 if (err
!= ERROR_SUCCESS
)
866 if (!load_package(name
, &package
, i
))
869 add_package(&package
);
874 if (!loaded_packages_count
) return;
876 provider
= SECUR32_addProvider(&lsa_sspi_tableA
, &lsa_sspi_tableW
, NULL
);
879 ERR("Failed to add SSP/AP provider\n");
883 for (i
= 0; i
< loaded_packages_count
; i
++)
887 info
= HeapAlloc(GetProcessHeap(), 0, loaded_packages
[i
].lsa_table_count
* sizeof(*info
));
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
)
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
;