2 * Copyright 2017 Dmitry Timoshkov
3 * Copyright 2017 George Popoff
4 * Copyright 2008 Robert Shearman for CodeWeavers
5 * Copyright 2017 Hans Leidekker for CodeWeavers
7 * Kerberos5 Authentication Package
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #define WIN32_NO_STATUS
37 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(kerberos
);
42 static HINSTANCE instance
;
44 unixlib_handle_t krb5_handle
= 0;
46 #define KERBEROS_CAPS \
47 ( SECPKG_FLAG_INTEGRITY \
48 | SECPKG_FLAG_PRIVACY \
49 | SECPKG_FLAG_TOKEN_ONLY \
50 | SECPKG_FLAG_DATAGRAM \
51 | SECPKG_FLAG_CONNECTION \
52 | SECPKG_FLAG_MULTI_REQUIRED \
53 | SECPKG_FLAG_EXTENDED_ERROR \
54 | SECPKG_FLAG_IMPERSONATION \
55 | SECPKG_FLAG_ACCEPT_WIN32_NAME \
56 | SECPKG_FLAG_NEGOTIABLE \
57 | SECPKG_FLAG_GSS_COMPATIBLE \
59 | SECPKG_FLAG_MUTUAL_AUTH \
60 | SECPKG_FLAG_DELEGATION \
61 | SECPKG_FLAG_READONLY_WITH_CHECKSUM \
62 | SECPKG_FLAG_RESTRICTED_TOKENS \
63 | SECPKG_FLAG_APPCONTAINER_CHECKS)
65 static WCHAR kerberos_name_W
[] = L
"Kerberos";
66 static WCHAR kerberos_comment_W
[] = L
"Microsoft Kerberos V1.0";
67 static const SecPkgInfoW infoW
=
71 RPC_C_AUTHN_GSS_KERBEROS
,
77 static ULONG kerberos_package_id
;
78 static LSA_DISPATCH_TABLE lsa_dispatch
;
80 static const char *debugstr_us( const UNICODE_STRING
*us
)
82 if (!us
) return "<null>";
83 return debugstr_wn( us
->Buffer
, us
->Length
/ sizeof(WCHAR
) );
86 static void expiry_to_timestamp( ULONG expiry
, TimeStamp
*timestamp
)
90 if (!timestamp
) return;
91 NtQuerySystemTime( &time
);
92 RtlSystemTimeToLocalTime( &time
, &time
);
93 time
.QuadPart
+= expiry
* (ULONGLONG
)10000000;
94 timestamp
->LowPart
= time
.QuadPart
;
95 timestamp
->HighPart
= time
.QuadPart
>> 32;
98 static NTSTATUS NTAPI
kerberos_LsaApInitializePackage(ULONG package_id
, PLSA_DISPATCH_TABLE dispatch
,
99 PLSA_STRING database
, PLSA_STRING confidentiality
, PLSA_STRING
*package_name
)
105 if (NtQueryVirtualMemory( GetCurrentProcess(), instance
, MemoryWineUnixFuncs
,
106 &krb5_handle
, sizeof(krb5_handle
), NULL
) ||
107 KRB5_CALL( process_attach
, NULL
))
108 ERR( "no Kerberos support, expect problems\n" );
111 kerberos_package_id
= package_id
;
112 lsa_dispatch
= *dispatch
;
114 kerberos_name
= lsa_dispatch
.AllocateLsaHeap(sizeof(MICROSOFT_KERBEROS_NAME_A
));
115 if (!kerberos_name
) return STATUS_NO_MEMORY
;
117 memcpy(kerberos_name
, MICROSOFT_KERBEROS_NAME_A
, sizeof(MICROSOFT_KERBEROS_NAME_A
));
119 *package_name
= lsa_dispatch
.AllocateLsaHeap(sizeof(**package_name
));
122 lsa_dispatch
.FreeLsaHeap(kerberos_name
);
123 return STATUS_NO_MEMORY
;
126 RtlInitString(*package_name
, kerberos_name
);
128 return STATUS_SUCCESS
;
131 static NTSTATUS
copy_to_client( PLSA_CLIENT_REQUEST lsa_req
, KERB_QUERY_TKT_CACHE_RESPONSE
*resp
,
132 void **out
, ULONG size
)
137 KERB_QUERY_TKT_CACHE_RESPONSE
*client_resp
;
139 status
= lsa_dispatch
.AllocateClientBuffer(lsa_req
, size
, out
);
140 if (status
!= STATUS_SUCCESS
) return status
;
143 status
= lsa_dispatch
.CopyToClientBuffer(lsa_req
, offsetof(KERB_QUERY_TKT_CACHE_RESPONSE
, Tickets
),
145 if (status
!= STATUS_SUCCESS
) goto fail
;
147 client_str
= (char *)&client_resp
->Tickets
[resp
->CountOfTickets
];
149 for (i
= 0; i
< resp
->CountOfTickets
; i
++)
151 KERB_TICKET_CACHE_INFO ticket
= resp
->Tickets
[i
];
153 RtlSecondsSince1970ToTime( resp
->Tickets
[i
].StartTime
.QuadPart
, &ticket
.StartTime
);
154 RtlSecondsSince1970ToTime( resp
->Tickets
[i
].EndTime
.QuadPart
, &ticket
.EndTime
);
155 RtlSecondsSince1970ToTime( resp
->Tickets
[i
].RenewTime
.QuadPart
, &ticket
.RenewTime
);
157 status
= lsa_dispatch
.CopyToClientBuffer(lsa_req
, ticket
.RealmName
.MaximumLength
,
158 client_str
, ticket
.RealmName
.Buffer
);
159 if (status
!= STATUS_SUCCESS
) goto fail
;
160 ticket
.RealmName
.Buffer
= (WCHAR
*)client_str
;
161 client_str
+= ticket
.RealmName
.MaximumLength
;
163 status
= lsa_dispatch
.CopyToClientBuffer(lsa_req
, ticket
.ServerName
.MaximumLength
,
164 client_str
, ticket
.ServerName
.Buffer
);
165 if (status
!= STATUS_SUCCESS
) goto fail
;
166 ticket
.ServerName
.Buffer
= (WCHAR
*)client_str
;
167 client_str
+= ticket
.ServerName
.MaximumLength
;
169 status
= lsa_dispatch
.CopyToClientBuffer(lsa_req
, sizeof(ticket
), &client_resp
->Tickets
[i
], &ticket
);
170 if (status
!= STATUS_SUCCESS
) goto fail
;
172 return STATUS_SUCCESS
;
175 lsa_dispatch
.FreeClientBuffer(lsa_req
, client_resp
);
179 static NTSTATUS NTAPI
kerberos_LsaApCallPackageUntrusted(PLSA_CLIENT_REQUEST req
, void *in_buf
,
180 void *client_buf_base
, ULONG in_buf_len
, void **out_buf
, ULONG
*out_buf_len
, NTSTATUS
*ret_status
)
182 KERB_PROTOCOL_MESSAGE_TYPE msg
;
184 TRACE("%p, %p, %p, %lu, %p, %p, %p\n", req
, in_buf
, client_buf_base
, in_buf_len
, out_buf
, out_buf_len
, ret_status
);
186 if (!in_buf
|| in_buf_len
< sizeof(msg
)) return STATUS_INVALID_PARAMETER
;
188 msg
= *(KERB_PROTOCOL_MESSAGE_TYPE
*)in_buf
;
191 case KerbQueryTicketCacheMessage
:
193 KERB_QUERY_TKT_CACHE_REQUEST
*query
= (KERB_QUERY_TKT_CACHE_REQUEST
*)in_buf
;
196 if (!in_buf
|| in_buf_len
!= sizeof(*query
) || !out_buf
|| !out_buf_len
) return STATUS_INVALID_PARAMETER
;
197 if (query
->LogonId
.HighPart
|| query
->LogonId
.LowPart
) return STATUS_ACCESS_DENIED
;
202 KERB_QUERY_TKT_CACHE_RESPONSE
*resp
= malloc( *out_buf_len
);
203 struct query_ticket_cache_params params
= { resp
, out_buf_len
};
204 status
= KRB5_CALL( query_ticket_cache
, ¶ms
);
205 if (status
== STATUS_SUCCESS
) status
= copy_to_client( req
, resp
, out_buf
, *out_buf_len
);
207 if (status
!= STATUS_BUFFER_TOO_SMALL
) break;
209 *ret_status
= status
;
212 case KerbRetrieveTicketMessage
:
213 FIXME("KerbRetrieveTicketMessage stub\n");
214 *ret_status
= STATUS_NOT_IMPLEMENTED
;
217 case KerbPurgeTicketCacheMessage
:
218 FIXME("KerbPurgeTicketCacheMessage stub\n");
219 *ret_status
= STATUS_NOT_IMPLEMENTED
;
222 default: /* All other requests should call LsaApCallPackage */
223 WARN("%u => access denied\n", msg
);
224 *ret_status
= STATUS_ACCESS_DENIED
;
231 static NTSTATUS NTAPI
kerberos_SpGetInfo(SecPkgInfoW
*info
)
235 /* LSA will make a copy before forwarding the structure, so
236 * it's safe to put pointers to dynamic or constant data there.
240 return STATUS_SUCCESS
;
243 static char *get_str_unixcp( const UNICODE_STRING
*str
)
246 int len
= WideCharToMultiByte( CP_UNIXCP
, 0, str
->Buffer
, str
->Length
/ sizeof(WCHAR
), NULL
, 0, NULL
, NULL
);
247 if (!(ret
= malloc( len
+ 1 ))) return NULL
;
248 WideCharToMultiByte( CP_UNIXCP
, 0, str
->Buffer
, str
->Length
/ sizeof(WCHAR
), ret
, len
, NULL
, NULL
);
253 static char *get_username_unixcp( const WCHAR
*user
, ULONG user_len
, const WCHAR
*domain
, ULONG domain_len
)
255 int len_user
, len_domain
;
258 len_user
= WideCharToMultiByte( CP_UNIXCP
, 0, user
, user_len
, NULL
, 0, NULL
, NULL
);
259 len_domain
= WideCharToMultiByte( CP_UNIXCP
, 0, domain
, domain_len
, NULL
, 0, NULL
, NULL
);
260 if (!(ret
= malloc( len_user
+ len_domain
+ 2 ))) return NULL
;
262 WideCharToMultiByte( CP_UNIXCP
, 0, user
, user_len
, ret
, len_user
, NULL
, NULL
);
264 WideCharToMultiByte( CP_UNIXCP
, 0, domain
, domain_len
, ret
+ len_user
+ 1, len_domain
, NULL
, NULL
);
265 ret
[len_user
+ len_domain
+ 1] = 0;
269 static char *get_password_unixcp( const WCHAR
*passwd
, ULONG passwd_len
)
274 len
= WideCharToMultiByte( CP_UNIXCP
, WC_NO_BEST_FIT_CHARS
, passwd
, passwd_len
, NULL
, 0, NULL
, NULL
);
275 if (!(ret
= malloc( len
+ 1 ))) return NULL
;
276 WideCharToMultiByte( CP_UNIXCP
, 0, passwd
, passwd_len
, ret
, len
, NULL
, NULL
);
281 static NTSTATUS NTAPI
kerberos_SpAcquireCredentialsHandle(
282 UNICODE_STRING
*principal_us
, ULONG credential_use
, LUID
*logon_id
, void *auth_data
,
283 void *get_key_fn
, void *get_key_arg
, LSA_SEC_HANDLE
*credential
, TimeStamp
*expiry
)
285 char *principal
= NULL
, *username
= NULL
, *password
= NULL
;
286 SEC_WINNT_AUTH_IDENTITY_W
*id
= auth_data
;
287 NTSTATUS status
= SEC_E_INSUFFICIENT_MEMORY
;
290 TRACE( "%s, %#lx, %p, %p, %p, %p, %p, %p\n", debugstr_us(principal_us
), credential_use
,
291 logon_id
, auth_data
, get_key_fn
, get_key_arg
, credential
, expiry
);
293 if (principal_us
&& !(principal
= get_str_unixcp( principal_us
))) return SEC_E_INSUFFICIENT_MEMORY
;
296 if (id
->Flags
& SEC_WINNT_AUTH_IDENTITY_ANSI
)
298 FIXME( "ANSI identity not supported\n" );
299 status
= SEC_E_UNSUPPORTED_FUNCTION
;
302 if (!(username
= get_username_unixcp( id
->User
, id
->UserLength
, id
->Domain
, id
->DomainLength
))) goto done
;
303 if (!(password
= get_password_unixcp( id
->Password
, id
->PasswordLength
))) goto done
;
307 struct acquire_credentials_handle_params params
= { principal
, credential_use
, username
, password
,
308 credential
, &exptime
};
309 status
= KRB5_CALL( acquire_credentials_handle
, ¶ms
);
310 expiry_to_timestamp( exptime
, expiry
);
320 static NTSTATUS NTAPI
kerberos_SpFreeCredentialsHandle( LSA_SEC_HANDLE credential
)
322 TRACE( "%Ix\n", credential
);
323 if (!credential
) return SEC_E_INVALID_HANDLE
;
324 return KRB5_CALL( free_credentials_handle
, (void *)credential
);
327 static NTSTATUS NTAPI
kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential
, LSA_SEC_HANDLE context
,
328 UNICODE_STRING
*target_name
, ULONG context_req
, ULONG target_data_rep
, SecBufferDesc
*input
,
329 LSA_SEC_HANDLE
*new_context
, SecBufferDesc
*output
, ULONG
*context_attr
, TimeStamp
*expiry
,
330 BOOLEAN
*mapped_context
, SecBuffer
*context_data
)
332 static const ULONG supported
= ISC_REQ_CONFIDENTIALITY
| ISC_REQ_INTEGRITY
| ISC_REQ_SEQUENCE_DETECT
|
333 ISC_REQ_REPLAY_DETECT
| ISC_REQ_MUTUAL_AUTH
| ISC_REQ_USE_DCE_STYLE
|
334 ISC_REQ_IDENTIFY
| ISC_REQ_CONNECTION
;
339 TRACE( "%Ix, %Ix, %s, %#lx, %lu, %p, %p, %p, %p, %p, %p, %p\n", credential
, context
, debugstr_us(target_name
),
340 context_req
, target_data_rep
, input
, new_context
, output
, context_attr
, expiry
,
341 mapped_context
, context_data
);
342 if (context_req
& ~supported
) FIXME( "flags %#lx not supported\n", context_req
& ~supported
);
344 if (!context
&& !input
&& !credential
) return SEC_E_INVALID_HANDLE
;
345 if (target_name
&& !(target
= get_str_unixcp( target_name
))) return SEC_E_INSUFFICIENT_MEMORY
;
348 struct initialize_context_params params
= { credential
, context
, target
, context_req
, input
,
349 new_context
, output
, context_attr
, &exptime
};
350 status
= KRB5_CALL( initialize_context
, ¶ms
);
353 *mapped_context
= TRUE
;
354 expiry_to_timestamp( exptime
, expiry
);
357 /* FIXME: initialize context_data */
362 static NTSTATUS NTAPI
kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential
, LSA_SEC_HANDLE context
,
363 SecBufferDesc
*input
, ULONG context_req
, ULONG target_data_rep
, LSA_SEC_HANDLE
*new_context
,
364 SecBufferDesc
*output
, ULONG
*context_attr
, TimeStamp
*expiry
, BOOLEAN
*mapped_context
, SecBuffer
*context_data
)
366 NTSTATUS status
= SEC_E_INVALID_HANDLE
;
369 TRACE( "%Ix, %Ix, %#lx, %lu, %p, %p, %p, %p, %p, %p, %p\n", credential
, context
, context_req
, target_data_rep
,
370 input
, new_context
, output
, context_attr
, expiry
, mapped_context
, context_data
);
371 if (context_req
) FIXME( "ignoring flags %#lx\n", context_req
);
373 if (context
|| input
|| credential
)
375 struct accept_context_params params
= { credential
, context
, input
, new_context
, output
, context_attr
, &exptime
};
376 status
= KRB5_CALL( accept_context
, ¶ms
);
379 *mapped_context
= TRUE
;
380 expiry_to_timestamp( exptime
, expiry
);
382 /* FIXME: initialize context_data */
387 static NTSTATUS NTAPI
kerberos_SpDeleteContext( LSA_SEC_HANDLE context
)
389 TRACE( "%Ix\n", context
);
390 if (!context
) return SEC_E_INVALID_HANDLE
;
391 return KRB5_CALL( delete_context
, (void *)context
);
394 static SecPkgInfoW
*build_package_info( const SecPkgInfoW
*info
)
397 DWORD size_name
= (wcslen(info
->Name
) + 1) * sizeof(WCHAR
);
398 DWORD size_comment
= (wcslen(info
->Comment
) + 1) * sizeof(WCHAR
);
400 if (!(ret
= malloc( sizeof(*ret
) + size_name
+ size_comment
))) return NULL
;
401 ret
->fCapabilities
= info
->fCapabilities
;
402 ret
->wVersion
= info
->wVersion
;
403 ret
->wRPCID
= info
->wRPCID
;
404 ret
->cbMaxToken
= info
->cbMaxToken
;
405 ret
->Name
= (SEC_WCHAR
*)(ret
+ 1);
406 memcpy( ret
->Name
, info
->Name
, size_name
);
407 ret
->Comment
= (SEC_WCHAR
*)((char *)ret
->Name
+ size_name
);
408 memcpy( ret
->Comment
, info
->Comment
, size_comment
);
412 static NTSTATUS NTAPI
kerberos_SpQueryContextAttributes( LSA_SEC_HANDLE context
, ULONG attribute
, void *buffer
)
414 TRACE( "%Ix, %lu, %p\n", context
, attribute
, buffer
);
416 if (!context
) return SEC_E_INVALID_HANDLE
;
420 #define X(x) case (x) : FIXME(#x" stub\n"); break
421 X(SECPKG_ATTR_ACCESS_TOKEN
);
422 X(SECPKG_ATTR_AUTHORITY
);
423 X(SECPKG_ATTR_DCE_INFO
);
424 X(SECPKG_ATTR_KEY_INFO
);
425 X(SECPKG_ATTR_LIFESPAN
);
426 X(SECPKG_ATTR_NAMES
);
427 X(SECPKG_ATTR_NATIVE_NAMES
);
428 X(SECPKG_ATTR_PACKAGE_INFO
);
429 X(SECPKG_ATTR_PASSWORD_EXPIRY
);
430 X(SECPKG_ATTR_SESSION_KEY
);
431 X(SECPKG_ATTR_STREAM_SIZES
);
432 X(SECPKG_ATTR_TARGET_INFORMATION
);
433 case SECPKG_ATTR_SIZES
:
435 struct query_context_attributes_params params
= { context
, attribute
, buffer
};
436 return KRB5_CALL( query_context_attributes
, ¶ms
);
438 case SECPKG_ATTR_NEGOTIATION_INFO
:
440 SecPkgContext_NegotiationInfoW
*info
= (SecPkgContext_NegotiationInfoW
*)buffer
;
441 if (!(info
->PackageInfo
= build_package_info( &infoW
))) return SEC_E_INSUFFICIENT_MEMORY
;
442 info
->NegotiationState
= SECPKG_NEGOTIATION_COMPLETE
;
447 FIXME( "unknown attribute %lu\n", attribute
);
451 return SEC_E_UNSUPPORTED_FUNCTION
;
454 static NTSTATUS NTAPI
kerberos_SpInitialize(ULONG_PTR package_id
, SECPKG_PARAMETERS
*params
,
455 LSA_SECPKG_FUNCTION_TABLE
*lsa_function_table
)
457 TRACE("%Iu, %p, %p\n", package_id
, params
, lsa_function_table
);
461 if (NtQueryVirtualMemory( GetCurrentProcess(), instance
, MemoryWineUnixFuncs
,
462 &krb5_handle
, sizeof(krb5_handle
), NULL
) ||
463 KRB5_CALL( process_attach
, NULL
))
464 WARN( "no Kerberos support\n" );
465 return STATUS_UNSUCCESSFUL
;
467 return STATUS_SUCCESS
;
470 static NTSTATUS NTAPI
kerberos_SpShutdown(void)
473 return STATUS_SUCCESS
;
476 static SECPKG_FUNCTION_TABLE kerberos_table
=
478 kerberos_LsaApInitializePackage
, /* InitializePackage */
479 NULL
, /* LsaLogonUser */
480 NULL
, /* CallPackage */
481 NULL
, /* LogonTerminated */
482 kerberos_LsaApCallPackageUntrusted
, /* CallPackageUntrusted */
483 NULL
, /* CallPackagePassthrough */
484 NULL
, /* LogonUserEx */
485 NULL
, /* LogonUserEx2 */
486 kerberos_SpInitialize
,
489 NULL
, /* AcceptCredentials */
490 kerberos_SpAcquireCredentialsHandle
,
491 NULL
, /* SpQueryCredentialsAttributes */
492 kerberos_SpFreeCredentialsHandle
,
493 NULL
, /* SaveCredentials */
494 NULL
, /* GetCredentials */
495 NULL
, /* DeleteCredentials */
496 kerberos_SpInitLsaModeContext
,
497 kerberos_SpAcceptLsaModeContext
,
498 kerberos_SpDeleteContext
,
499 NULL
, /* ApplyControlToken */
500 NULL
, /* GetUserInfo */
501 NULL
, /* GetExtendedInformation */
502 kerberos_SpQueryContextAttributes
,
503 NULL
, /* SpAddCredentials */
504 NULL
, /* SetExtendedInformation */
505 NULL
, /* SetContextAttributes */
506 NULL
, /* SetCredentialsAttributes */
507 NULL
, /* ChangeAccountPassword */
508 NULL
, /* QueryMetaData */
509 NULL
, /* ExchangeMetaData */
510 NULL
, /* GetCredUIContext */
511 NULL
, /* UpdateCredentials */
512 NULL
, /* ValidateTargetInfo */
513 NULL
, /* PostLogonUser */
516 NTSTATUS NTAPI
SpLsaModeInitialize(ULONG lsa_version
, PULONG package_version
,
517 PSECPKG_FUNCTION_TABLE
*table
, PULONG table_count
)
519 TRACE("%#lx, %p, %p, %p\n", lsa_version
, package_version
, table
, table_count
);
521 *package_version
= SECPKG_INTERFACE_VERSION
;
522 *table
= &kerberos_table
;
524 return STATUS_SUCCESS
;
527 static NTSTATUS NTAPI
kerberos_SpInstanceInit(ULONG version
, SECPKG_DLL_FUNCTIONS
*dll_function_table
, void **user_functions
)
529 TRACE("%#lx, %p, %p\n", version
, dll_function_table
, user_functions
);
530 return STATUS_SUCCESS
;
533 static NTSTATUS SEC_ENTRY
kerberos_SpMakeSignature( LSA_SEC_HANDLE context
, ULONG quality_of_protection
,
534 SecBufferDesc
*message
, ULONG message_seq_no
)
536 TRACE( "%Ix, %#lx, %p, %lu\n", context
, quality_of_protection
, message
, message_seq_no
);
537 if (quality_of_protection
) FIXME( "ignoring quality_of_protection %#lx\n", quality_of_protection
);
538 if (message_seq_no
) FIXME( "ignoring message_seq_no %lu\n", message_seq_no
);
542 struct make_signature_params params
= { context
, message
};
543 return KRB5_CALL( make_signature
, ¶ms
);
545 else return SEC_E_INVALID_HANDLE
;
548 static NTSTATUS NTAPI
kerberos_SpVerifySignature( LSA_SEC_HANDLE context
, SecBufferDesc
*message
,
549 ULONG message_seq_no
, ULONG
*quality_of_protection
)
551 TRACE( "%Ix, %p, %lu, %p\n", context
, message
, message_seq_no
, quality_of_protection
);
552 if (message_seq_no
) FIXME( "ignoring message_seq_no %lu\n", message_seq_no
);
556 struct verify_signature_params params
= { context
, message
, quality_of_protection
};
557 return KRB5_CALL( verify_signature
, ¶ms
);
559 else return SEC_E_INVALID_HANDLE
;
562 static NTSTATUS NTAPI
kerberos_SpSealMessage( LSA_SEC_HANDLE context
, ULONG quality_of_protection
,
563 SecBufferDesc
*message
, ULONG message_seq_no
)
565 TRACE( "%Ix, %#lx, %p, %lu\n", context
, quality_of_protection
, message
, message_seq_no
);
566 if (message_seq_no
) FIXME( "ignoring message_seq_no %lu\n", message_seq_no
);
570 struct seal_message_params params
= { context
, message
, quality_of_protection
};
571 return KRB5_CALL( seal_message
, ¶ms
);
573 else return SEC_E_INVALID_HANDLE
;
576 static NTSTATUS NTAPI
kerberos_SpUnsealMessage( LSA_SEC_HANDLE context
, SecBufferDesc
*message
,
577 ULONG message_seq_no
, ULONG
*quality_of_protection
)
579 TRACE( "%Ix, %p, %lu, %p\n", context
, message
, message_seq_no
, quality_of_protection
);
580 if (message_seq_no
) FIXME( "ignoring message_seq_no %lu\n", message_seq_no
);
584 struct unseal_message_params params
= { context
, message
, quality_of_protection
};
585 return KRB5_CALL( unseal_message
, ¶ms
);
587 else return SEC_E_INVALID_HANDLE
;
590 static SECPKG_USER_FUNCTION_TABLE kerberos_user_table
=
592 kerberos_SpInstanceInit
,
593 NULL
, /* SpInitUserModeContext */
594 kerberos_SpMakeSignature
,
595 kerberos_SpVerifySignature
,
596 kerberos_SpSealMessage
,
597 kerberos_SpUnsealMessage
,
598 NULL
, /* SpGetContextToken */
599 NULL
, /* SpQueryContextAttributes */
600 NULL
, /* SpCompleteAuthToken */
601 NULL
, /* SpDeleteContext */
602 NULL
, /* SpFormatCredentialsFn */
603 NULL
, /* SpMarshallSupplementalCreds */
604 NULL
, /* SpExportSecurityContext */
605 NULL
/* SpImportSecurityContext */
608 NTSTATUS NTAPI
SpUserModeInitialize(ULONG lsa_version
, PULONG package_version
,
609 PSECPKG_USER_FUNCTION_TABLE
*table
, PULONG table_count
)
611 TRACE("%#lx, %p, %p, %p\n", lsa_version
, package_version
, table
, table_count
);
613 *package_version
= SECPKG_INTERFACE_VERSION
;
614 *table
= &kerberos_user_table
;
616 return STATUS_SUCCESS
;
619 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, void *reserved
)
623 case DLL_PROCESS_ATTACH
:
625 DisableThreadLibraryCalls( hinst
);
627 case DLL_PROCESS_DETACH
: