From 099063f0fc37ddb49d30050b1637ffe9c11b23e1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 4 Nov 2021 20:50:53 +0100 Subject: [PATCH] kerberos: Convert the Unix library to the __wine_unix_call interface. Signed-off-by: Alexandre Julliard --- dlls/kerberos/Makefile.in | 1 + dlls/kerberos/krb5_ap.c | 102 ++++++++++++++++-------- dlls/kerberos/unixlib.c | 159 +++++++++++++++++++------------------- dlls/kerberos/unixlib.h | 108 ++++++++++++++++++++++---- 4 files changed, 242 insertions(+), 128 deletions(-) diff --git a/dlls/kerberos/Makefile.in b/dlls/kerberos/Makefile.in index ab5e6b59976..8dcd4f9c7da 100644 --- a/dlls/kerberos/Makefile.in +++ b/dlls/kerberos/Makefile.in @@ -1,4 +1,5 @@ MODULE = kerberos.dll +UNIXLIB = kerberos.so EXTRAINCL = $(KRB5_CFLAGS) $(GSSAPI_CFLAGS) C_SRCS = \ diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index 9105e3d2c5d..8295d2e103e 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -41,7 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(kerberos); static HINSTANCE instance; -const struct krb5_funcs *krb5_funcs = NULL; +unixlib_handle_t krb5_handle = 0; #define KERBEROS_CAPS \ ( SECPKG_FLAG_INTEGRITY \ @@ -99,8 +99,13 @@ static NTSTATUS NTAPI kerberos_LsaApInitializePackage(ULONG package_id, PLSA_DIS { char *kerberos_name; - if (!krb5_funcs && __wine_init_unix_lib( instance, DLL_PROCESS_ATTACH, NULL, &krb5_funcs )) - ERR( "no Kerberos support, expect problems\n" ); + if (!krb5_handle) + { + if (NtQueryVirtualMemory( GetCurrentProcess(), instance, MemoryWineUnixFuncs, + &krb5_handle, sizeof(krb5_handle), NULL ) || + KRB5_CALL( process_attach, NULL )) + ERR( "no Kerberos support, expect problems\n" ); + } kerberos_package_id = package_id; lsa_dispatch = *dispatch; @@ -194,7 +199,8 @@ static NTSTATUS NTAPI kerberos_LsaApCallPackageUntrusted(PLSA_CLIENT_REQUEST req for (;;) { KERB_QUERY_TKT_CACHE_RESPONSE *resp = malloc( *out_buf_len ); - status = krb5_funcs->query_ticket_cache( resp, out_buf_len ); + struct query_ticket_cache_params params = { resp, out_buf_len }; + status = KRB5_CALL( query_ticket_cache, ¶ms ); if (status == STATUS_SUCCESS) status = copy_to_client( req, resp, out_buf, *out_buf_len ); free( resp ); if (status != STATUS_BUFFER_TOO_SMALL) break; @@ -296,9 +302,12 @@ static NTSTATUS NTAPI kerberos_SpAcquireCredentialsHandle( if (!(password = get_password_unixcp( id->Password, id->PasswordLength ))) goto done; } - status = krb5_funcs->acquire_credentials_handle( principal, credential_use, username, password, credential, - &exptime ); - expiry_to_timestamp( exptime, expiry ); + { + struct acquire_credentials_handle_params params = { principal, credential_use, username, password, + credential, &exptime }; + status = KRB5_CALL( acquire_credentials_handle, ¶ms ); + expiry_to_timestamp( exptime, expiry ); + } done: free( principal ); @@ -311,7 +320,7 @@ static NTSTATUS NTAPI kerberos_SpFreeCredentialsHandle( LSA_SEC_HANDLE credentia { TRACE( "(%lx)\n", credential ); if (!credential) return SEC_E_INVALID_HANDLE; - return krb5_funcs->free_credentials_handle( credential ); + return KRB5_CALL( free_credentials_handle, (void *)credential ); } static NTSTATUS NTAPI kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential, LSA_SEC_HANDLE context, @@ -333,13 +342,16 @@ static NTSTATUS NTAPI kerberos_SpInitLsaModeContext( LSA_SEC_HANDLE credential, if (!context && !input && !credential) return SEC_E_INVALID_HANDLE; if (target_name && !(target = get_str_unixcp( target_name ))) return SEC_E_INSUFFICIENT_MEMORY; - - status = krb5_funcs->initialize_context( credential, context, target, context_req, input, new_context, output, - context_attr, &exptime ); - if (!status) + else { - *mapped_context = TRUE; - expiry_to_timestamp( exptime, expiry ); + struct initialize_context_params params = { credential, context, target, context_req, input, + new_context, output, context_attr, &exptime }; + status = KRB5_CALL( initialize_context, ¶ms ); + if (!status) + { + *mapped_context = TRUE; + expiry_to_timestamp( exptime, expiry ); + } } /* FIXME: initialize context_data */ free( target ); @@ -350,22 +362,24 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential SecBufferDesc *input, ULONG context_req, ULONG target_data_rep, LSA_SEC_HANDLE *new_context, SecBufferDesc *output, ULONG *context_attr, TimeStamp *expiry, BOOLEAN *mapped_context, SecBuffer *context_data ) { - NTSTATUS status; + NTSTATUS status = SEC_E_INVALID_HANDLE; ULONG exptime; TRACE( "(%lx %lx 0x%08x %u %p %p %p %p %p %p %p)\n", credential, context, context_req, target_data_rep, input, new_context, output, context_attr, expiry, mapped_context, context_data ); if (context_req) FIXME( "ignoring flags 0x%08x\n", context_req ); - if (!context && !input && !credential) return SEC_E_INVALID_HANDLE; - - status = krb5_funcs->accept_context( credential, context, input, new_context, output, context_attr, &exptime ); - if (!status) + if (context || input || credential) { - *mapped_context = TRUE; - expiry_to_timestamp( exptime, expiry ); + struct accept_context_params params = { credential, context, input, new_context, output, context_attr, &exptime }; + status = KRB5_CALL( accept_context, ¶ms ); + if (!status) + { + *mapped_context = TRUE; + expiry_to_timestamp( exptime, expiry ); + } + /* FIXME: initialize context_data */ } - /* FIXME: initialize context_data */ return status; } @@ -373,7 +387,7 @@ static NTSTATUS NTAPI kerberos_SpDeleteContext( LSA_SEC_HANDLE context ) { TRACE( "(%lx)\n", context ); if (!context) return SEC_E_INVALID_HANDLE; - return krb5_funcs->delete_context( context ); + return KRB5_CALL( delete_context, (void *)context ); } static SecPkgInfoW *build_package_info( const SecPkgInfoW *info ) @@ -417,7 +431,8 @@ static NTSTATUS NTAPI kerberos_SpQueryContextAttributes( LSA_SEC_HANDLE context, X(SECPKG_ATTR_TARGET_INFORMATION); case SECPKG_ATTR_SIZES: { - return krb5_funcs->query_context_attributes( context, attribute, buffer ); + struct query_context_attributes_params params = { context, attribute, buffer }; + return KRB5_CALL( query_context_attributes, ¶ms ); } case SECPKG_ATTR_NEGOTIATION_INFO: { @@ -440,9 +455,12 @@ static NTSTATUS NTAPI kerberos_SpInitialize(ULONG_PTR package_id, SECPKG_PARAMET { TRACE("%lu,%p,%p\n", package_id, params, lsa_function_table); - if (!krb5_funcs && __wine_init_unix_lib( instance, DLL_PROCESS_ATTACH, NULL, &krb5_funcs )) + if (!krb5_handle) { - WARN( "no Kerberos support\n" ); + if (NtQueryVirtualMemory( GetCurrentProcess(), instance, MemoryWineUnixFuncs, + &krb5_handle, sizeof(krb5_handle), NULL ) || + KRB5_CALL( process_attach, NULL )) + WARN( "no Kerberos support\n" ); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; @@ -518,8 +536,12 @@ static NTSTATUS SEC_ENTRY kerberos_SpMakeSignature( LSA_SEC_HANDLE context, ULON if (quality_of_protection) FIXME( "ignoring quality_of_protection 0x%08x\n", quality_of_protection ); if (message_seq_no) FIXME( "ignoring message_seq_no %u\n", message_seq_no ); - if (!context) return SEC_E_INVALID_HANDLE; - return krb5_funcs->make_signature( context, message ); + if (context) + { + struct make_signature_params params = { context, message }; + return KRB5_CALL( make_signature, ¶ms ); + } + else return SEC_E_INVALID_HANDLE; } static NTSTATUS NTAPI kerberos_SpVerifySignature( LSA_SEC_HANDLE context, SecBufferDesc *message, @@ -528,8 +550,12 @@ static NTSTATUS NTAPI kerberos_SpVerifySignature( LSA_SEC_HANDLE context, SecBuf TRACE( "(%lx %p %u %p)\n", context, message, message_seq_no, quality_of_protection ); if (message_seq_no) FIXME( "ignoring message_seq_no %u\n", message_seq_no ); - if (!context) return SEC_E_INVALID_HANDLE; - return krb5_funcs->verify_signature( context, message, quality_of_protection ); + if (context) + { + struct verify_signature_params params = { context, message, quality_of_protection }; + return KRB5_CALL( verify_signature, ¶ms ); + } + else return SEC_E_INVALID_HANDLE; } static NTSTATUS NTAPI kerberos_SpSealMessage( LSA_SEC_HANDLE context, ULONG quality_of_protection, @@ -538,8 +564,12 @@ static NTSTATUS NTAPI kerberos_SpSealMessage( LSA_SEC_HANDLE context, ULONG qual TRACE( "(%lx 0x%08x %p %u)\n", context, quality_of_protection, message, message_seq_no ); if (message_seq_no) FIXME( "ignoring message_seq_no %u\n", message_seq_no ); - if (!context) return SEC_E_INVALID_HANDLE; - return krb5_funcs->seal_message( context, message, quality_of_protection ); + if (context) + { + struct seal_message_params params = { context, message, quality_of_protection }; + return KRB5_CALL( seal_message, ¶ms ); + } + else return SEC_E_INVALID_HANDLE; } static NTSTATUS NTAPI kerberos_SpUnsealMessage( LSA_SEC_HANDLE context, SecBufferDesc *message, @@ -548,8 +578,12 @@ static NTSTATUS NTAPI kerberos_SpUnsealMessage( LSA_SEC_HANDLE context, SecBuffe TRACE( "(%lx %p %u %p)\n", context, message, message_seq_no, quality_of_protection ); if (message_seq_no) FIXME( "ignoring message_seq_no %u\n", message_seq_no ); - if (!context) return SEC_E_INVALID_HANDLE; - return krb5_funcs->unseal_message( context, message, quality_of_protection ); + if (context) + { + struct unseal_message_params params = { context, message, quality_of_protection }; + return KRB5_CALL( unseal_message, ¶ms ); + } + else return SEC_E_INVALID_HANDLE; } static SECPKG_USER_FUNCTION_TABLE kerberos_user_table = diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 4024cc4bec1..2ee19d6fe69 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -303,8 +303,9 @@ static NTSTATUS copy_tickets_to_client( struct ticket_list *list, KERB_QUERY_TKT return STATUS_SUCCESS; } -static NTSTATUS CDECL query_ticket_cache( KERB_QUERY_TKT_CACHE_RESPONSE *resp, ULONG *out_size ) +static NTSTATUS query_ticket_cache( void *args ) { + struct query_ticket_cache_params *params = args; NTSTATUS status; krb5_error_code err; krb5_context ctx; @@ -338,7 +339,7 @@ done: if (cursor) p_krb5_cccol_cursor_free( ctx, &cursor ); if (ctx) p_krb5_free_context( ctx ); - if (status == STATUS_SUCCESS) status = copy_tickets_to_client( &list, resp, out_size ); + if (status == STATUS_SUCCESS) status = copy_tickets_to_client( &list, params->resp, params->out_size ); for (i = 0; i < list.count; i++) { @@ -520,25 +521,24 @@ static ULONG flags_gss_to_asc_ret( ULONG flags ) return ret; } -static NTSTATUS CDECL accept_context( LSA_SEC_HANDLE credential, LSA_SEC_HANDLE context, SecBufferDesc *input, - LSA_SEC_HANDLE *new_context, SecBufferDesc *output, ULONG *context_attr, - ULONG *expiry ) +static NTSTATUS accept_context( void *args ) { + struct accept_context_params *params = args; OM_uint32 ret, minor_status, ret_flags = 0, expiry_time; - gss_cred_id_t cred_handle = credhandle_sspi_to_gss( credential ); - gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( context ); + gss_cred_id_t cred_handle = credhandle_sspi_to_gss( params->credential ); + gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context ); gss_buffer_desc input_token, output_token; int idx; - if (!input) input_token.length = 0; + if (!params->input) input_token.length = 0; else { - if ((idx = get_buffer_index( input, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; - input_token.length = input->pBuffers[idx].cbBuffer; - input_token.value = input->pBuffers[idx].pvBuffer; + if ((idx = get_buffer_index( params->input, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + input_token.length = params->input->pBuffers[idx].cbBuffer; + input_token.value = params->input->pBuffers[idx].pvBuffer; } - if ((idx = get_buffer_index( output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + if ((idx = get_buffer_index( params->output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; output_token.length = 0; output_token.value = NULL; @@ -548,20 +548,20 @@ static NTSTATUS CDECL accept_context( LSA_SEC_HANDLE credential, LSA_SEC_HANDLE if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - if (output_token.length > output->pBuffers[idx].cbBuffer) /* FIXME: check if larger buffer exists */ + if (output_token.length > params->output->pBuffers[idx].cbBuffer) /* FIXME: check if larger buffer exists */ { - TRACE( "buffer too small %lu > %u\n", (SIZE_T)output_token.length, output->pBuffers[idx].cbBuffer ); + TRACE( "buffer too small %lu > %u\n", (SIZE_T)output_token.length, params->output->pBuffers[idx].cbBuffer ); pgss_release_buffer( &minor_status, &output_token ); pgss_delete_sec_context( &minor_status, &ctx_handle, GSS_C_NO_BUFFER ); return SEC_E_BUFFER_TOO_SMALL; } - output->pBuffers[idx].cbBuffer = output_token.length; - memcpy( output->pBuffers[idx].pvBuffer, output_token.value, output_token.length ); + params->output->pBuffers[idx].cbBuffer = output_token.length; + memcpy( params->output->pBuffers[idx].pvBuffer, output_token.value, output_token.length ); pgss_release_buffer( &minor_status, &output_token ); - ctxhandle_gss_to_sspi( ctx_handle, new_context ); - if (context_attr) *context_attr = flags_gss_to_asc_ret( ret_flags ); - *expiry = expiry_time; + ctxhandle_gss_to_sspi( ctx_handle, params->new_context ); + if (params->context_attr) *params->context_attr = flags_gss_to_asc_ret( ret_flags ); + *params->expiry = expiry_time; } return status_gss_to_sspi( ret ); @@ -610,23 +610,23 @@ static NTSTATUS import_name( const char *src, gss_name_t *dst ) return status_gss_to_sspi( ret ); } -static NTSTATUS CDECL acquire_credentials_handle( const char *principal, ULONG credential_use, const char *username, - const char *password, LSA_SEC_HANDLE *credential, ULONG *expiry ) +static NTSTATUS acquire_credentials_handle( void *args ) { + struct acquire_credentials_handle_params *params = args; OM_uint32 ret, minor_status, expiry_time; gss_name_t name = GSS_C_NO_NAME; gss_cred_usage_t cred_usage; gss_cred_id_t cred_handle; NTSTATUS status; - switch (credential_use) + switch (params->credential_use) { case SECPKG_CRED_INBOUND: cred_usage = GSS_C_ACCEPT; break; case SECPKG_CRED_OUTBOUND: - if ((status = init_creds( username, password )) != STATUS_SUCCESS) return status; + if ((status = init_creds( params->username, params->password )) != STATUS_SUCCESS) return status; cred_usage = GSS_C_INITIATE; break; @@ -635,7 +635,7 @@ static NTSTATUS CDECL acquire_credentials_handle( const char *principal, ULONG c return SEC_E_UNKNOWN_CREDENTIALS; } - if (principal && (status = import_name( principal, &name ))) return status; + if (params->principal && (status = import_name( params->principal, &name ))) return status; ret = pgss_acquire_cred( &minor_status, name, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, cred_usage, &cred_handle, NULL, &expiry_time ); @@ -643,18 +643,18 @@ static NTSTATUS CDECL acquire_credentials_handle( const char *principal, ULONG c if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE) { - credhandle_gss_to_sspi( cred_handle, credential ); - *expiry = expiry_time; + credhandle_gss_to_sspi( cred_handle, params->credential ); + *params->expiry = expiry_time; } if (name != GSS_C_NO_NAME) pgss_release_name( &minor_status, &name ); return status_gss_to_sspi( ret ); } -static NTSTATUS CDECL delete_context( LSA_SEC_HANDLE context ) +static NTSTATUS delete_context( void *args ) { OM_uint32 ret, minor_status; - gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( context ); + gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( (LSA_SEC_HANDLE)args ); ret = pgss_delete_sec_context( &minor_status, &ctx_handle, GSS_C_NO_BUFFER ); TRACE( "gss_delete_sec_context returned %08x minor status %08x\n", ret, minor_status ); @@ -662,10 +662,10 @@ static NTSTATUS CDECL delete_context( LSA_SEC_HANDLE context ) return status_gss_to_sspi( ret ); } -static NTSTATUS CDECL free_credentials_handle( LSA_SEC_HANDLE handle ) +static NTSTATUS free_credentials_handle( void *args ) { OM_uint32 ret, minor_status; - gss_cred_id_t cred = credhandle_sspi_to_gss( handle ); + gss_cred_id_t cred = credhandle_sspi_to_gss( (LSA_SEC_HANDLE)args ); ret = pgss_release_cred( &minor_status, &cred ); TRACE( "gss_release_cred returned %08x minor status %08x\n", ret, minor_status ); @@ -703,30 +703,29 @@ static ULONG flags_gss_to_isc_ret( ULONG flags ) return ret; } -static NTSTATUS CDECL initialize_context( LSA_SEC_HANDLE credential, LSA_SEC_HANDLE context, const char *target_name, - ULONG context_req, SecBufferDesc *input, LSA_SEC_HANDLE *new_context, - SecBufferDesc *output, ULONG *context_attr, ULONG *expiry ) +static NTSTATUS initialize_context( void *args ) { - OM_uint32 ret, minor_status, ret_flags = 0, expiry_time, req_flags = flags_isc_req_to_gss( context_req ); - gss_cred_id_t cred_handle = credhandle_sspi_to_gss( credential ); - gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( context ); + struct initialize_context_params *params = args; + OM_uint32 ret, minor_status, ret_flags = 0, expiry_time, req_flags = flags_isc_req_to_gss( params->context_req ); + gss_cred_id_t cred_handle = credhandle_sspi_to_gss( params->credential ); + gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context ); gss_buffer_desc input_token, output_token; gss_name_t target = GSS_C_NO_NAME; NTSTATUS status; int idx; - if ((idx = get_buffer_index( input, SECBUFFER_TOKEN )) == -1) input_token.length = 0; + if ((idx = get_buffer_index( params->input, SECBUFFER_TOKEN )) == -1) input_token.length = 0; else { - input_token.length = input->pBuffers[idx].cbBuffer; - input_token.value = input->pBuffers[idx].pvBuffer; + input_token.length = params->input->pBuffers[idx].cbBuffer; + input_token.value = params->input->pBuffers[idx].pvBuffer; } - if ((idx = get_buffer_index( output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + if ((idx = get_buffer_index( params->output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; output_token.length = 0; output_token.value = NULL; - if (target_name && (status = import_name( target_name, &target ))) return status; + if (params->target_name && (status = import_name( params->target_name, &target ))) return status; ret = pgss_init_sec_context( &minor_status, cred_handle, &ctx_handle, target, GSS_C_NO_OID, req_flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &input_token, NULL, &output_token, &ret_flags, @@ -735,31 +734,33 @@ static NTSTATUS CDECL initialize_context( LSA_SEC_HANDLE credential, LSA_SEC_HAN if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - if (output_token.length > output->pBuffers[idx].cbBuffer) /* FIXME: check if larger buffer exists */ + if (output_token.length > params->output->pBuffers[idx].cbBuffer) /* FIXME: check if larger buffer exists */ { - TRACE( "buffer too small %lu > %u\n", (SIZE_T)output_token.length, output->pBuffers[idx].cbBuffer ); + TRACE( "buffer too small %lu > %u\n", (SIZE_T)output_token.length, params->output->pBuffers[idx].cbBuffer ); pgss_release_buffer( &minor_status, &output_token ); pgss_delete_sec_context( &minor_status, &ctx_handle, GSS_C_NO_BUFFER ); return SEC_E_INCOMPLETE_MESSAGE; } - output->pBuffers[idx].cbBuffer = output_token.length; - memcpy( output->pBuffers[idx].pvBuffer, output_token.value, output_token.length ); + params->output->pBuffers[idx].cbBuffer = output_token.length; + memcpy( params->output->pBuffers[idx].pvBuffer, output_token.value, output_token.length ); pgss_release_buffer( &minor_status, &output_token ); - ctxhandle_gss_to_sspi( ctx_handle, new_context ); - if (context_attr) *context_attr = flags_gss_to_isc_ret( ret_flags ); - *expiry = expiry_time; + ctxhandle_gss_to_sspi( ctx_handle, params->new_context ); + if (params->context_attr) *params->context_attr = flags_gss_to_isc_ret( ret_flags ); + *params->expiry = expiry_time; } if (target != GSS_C_NO_NAME) pgss_release_name( &minor_status, &target ); return status_gss_to_sspi( ret ); } -static NTSTATUS CDECL make_signature( LSA_SEC_HANDLE context, SecBufferDesc *msg ) +static NTSTATUS make_signature( void *args ) { + struct make_signature_params *params = args; + SecBufferDesc *msg = params->msg; OM_uint32 ret, minor_status; gss_buffer_desc data_buffer, token_buffer; - gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( context ); + gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context ); int data_idx, token_idx; /* FIXME: multiple data buffers, read-only buffers */ @@ -789,15 +790,16 @@ static NTSTATUS CDECL make_signature( LSA_SEC_HANDLE context, SecBufferDesc *msg #define KERBEROS_MAX_SIGNATURE_DCE 28 #define KERBEROS_SECURITY_TRAILER_DCE 76 -static NTSTATUS CDECL query_context_attributes( LSA_SEC_HANDLE context, ULONG attr, void *buf ) +static NTSTATUS query_context_attributes( void *args ) { - switch (attr) + struct query_context_attributes_params *params = args; + switch (params->attr) { case SECPKG_ATTR_SIZES: { - SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)buf; + SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)params->buf; ULONG size_max_signature, size_security_trailer; - gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( context ); + gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( params->context ); if (is_dce_style_context( ctx )) { @@ -816,7 +818,7 @@ static NTSTATUS CDECL query_context_attributes( LSA_SEC_HANDLE context, ULONG at return SEC_E_OK; } default: - FIXME( "unhandled attribute %u\n", attr ); + FIXME( "unhandled attribute %u\n", params->attr ); break; } @@ -916,12 +918,13 @@ static NTSTATUS seal_message_no_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, UL return status_gss_to_sspi( ret ); } -static NTSTATUS CDECL seal_message( LSA_SEC_HANDLE context, SecBufferDesc *msg, ULONG qop ) +static NTSTATUS seal_message( void *args ) { - gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( context ); + struct seal_message_params *params = args; + gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( params->context ); - if (is_dce_style_context( ctx )) return seal_message_vector( ctx, msg, qop ); - return seal_message_no_vector( ctx, msg, qop ); + if (is_dce_style_context( ctx )) return seal_message_vector( ctx, params->msg, params->qop ); + return seal_message_no_vector( ctx, params->msg, params->qop ); } static NTSTATUS unseal_message_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, ULONG *qop ) @@ -991,19 +994,22 @@ static NTSTATUS unseal_message_no_vector( gss_ctx_id_t ctx, SecBufferDesc *msg, return status_gss_to_sspi( ret ); } -static NTSTATUS CDECL unseal_message( LSA_SEC_HANDLE context, SecBufferDesc *msg, ULONG *qop ) +static NTSTATUS unseal_message( void *args ) { - gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( context ); + struct unseal_message_params *params = args; + gss_ctx_id_t ctx = ctxhandle_sspi_to_gss( params->context ); - if (is_dce_style_context( ctx )) return unseal_message_vector( ctx, msg, qop ); - return unseal_message_no_vector( ctx, msg, qop ); + if (is_dce_style_context( ctx )) return unseal_message_vector( ctx, params->msg, params->qop ); + return unseal_message_no_vector( ctx, params->msg, params->qop ); } -static NTSTATUS CDECL verify_signature( LSA_SEC_HANDLE context, SecBufferDesc *msg, ULONG *qop ) +static NTSTATUS verify_signature( void *args ) { + struct verify_signature_params *params = args; + SecBufferDesc *msg = params->msg; OM_uint32 ret, minor_status; gss_buffer_desc data_buffer, token_buffer; - gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( context ); + gss_ctx_id_t ctx_handle = ctxhandle_sspi_to_gss( params->context ); int data_idx, token_idx; if ((data_idx = get_buffer_index( msg, SECBUFFER_DATA )) == -1) return SEC_E_INVALID_TOKEN; @@ -1017,13 +1023,21 @@ static NTSTATUS CDECL verify_signature( LSA_SEC_HANDLE context, SecBufferDesc *m ret = pgss_verify_mic( &minor_status, ctx_handle, &data_buffer, &token_buffer, NULL ); TRACE( "gss_verify_mic returned %08x minor status %08x\n", ret, minor_status ); if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); - if (ret == GSS_S_COMPLETE && qop) *qop = 0; + if (ret == GSS_S_COMPLETE && params->qop) *params->qop = 0; return status_gss_to_sspi( ret ); } -static const struct krb5_funcs funcs = +static NTSTATUS process_attach( void *args ) { + if (load_krb5() && load_gssapi_krb5()) return STATUS_SUCCESS; + if (libkrb5_handle) unload_krb5(); + return STATUS_DLL_NOT_FOUND; +} + +unixlib_entry_t __wine_unix_call_funcs[] = +{ + process_attach, accept_context, acquire_credentials_handle, delete_context, @@ -1037,15 +1051,4 @@ static const struct krb5_funcs funcs = verify_signature, }; -NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) -{ - if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS; - if (load_krb5() && load_gssapi_krb5()) - { - *(const struct krb5_funcs **)ptr_out = &funcs; - return STATUS_SUCCESS; - } - if (libkrb5_handle) unload_krb5(); - return STATUS_DLL_NOT_FOUND; -} #endif /* defined(SONAME_LIBKRB5) && defined(SONAME_LIBGSSAPI_KRB5) */ diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 2d0cb45f979..05b24d6fadf 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -19,24 +19,100 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "wine/unixlib.h" + #define KERBEROS_MAX_BUF 12000 -struct krb5_funcs +struct accept_context_params { - NTSTATUS (CDECL *accept_context)(LSA_SEC_HANDLE, LSA_SEC_HANDLE, SecBufferDesc *, LSA_SEC_HANDLE *, - SecBufferDesc *, ULONG *, ULONG *); - NTSTATUS (CDECL *acquire_credentials_handle)(const char *, ULONG, const char *, const char *, LSA_SEC_HANDLE *, - ULONG *); - NTSTATUS (CDECL *delete_context)(LSA_SEC_HANDLE); - NTSTATUS (CDECL *free_credentials_handle)(LSA_SEC_HANDLE); - NTSTATUS (CDECL *initialize_context)(LSA_SEC_HANDLE, LSA_SEC_HANDLE, const char *, ULONG, SecBufferDesc *, - LSA_SEC_HANDLE *, SecBufferDesc *, ULONG *, ULONG *); - NTSTATUS (CDECL *make_signature)(LSA_SEC_HANDLE, SecBufferDesc *); - NTSTATUS (CDECL *query_context_attributes)(LSA_SEC_HANDLE, ULONG, void *); - NTSTATUS (CDECL *query_ticket_cache)( KERB_QUERY_TKT_CACHE_RESPONSE *resp, ULONG *out_size ); - NTSTATUS (CDECL *seal_message)(LSA_SEC_HANDLE, SecBufferDesc *, ULONG); - NTSTATUS (CDECL *unseal_message)(LSA_SEC_HANDLE, SecBufferDesc *, ULONG *); - NTSTATUS (CDECL *verify_signature)(LSA_SEC_HANDLE, SecBufferDesc *, ULONG *); + LSA_SEC_HANDLE credential; + LSA_SEC_HANDLE context; + SecBufferDesc *input; + LSA_SEC_HANDLE *new_context; + SecBufferDesc *output; + ULONG *context_attr; + ULONG *expiry; }; -extern const struct krb5_funcs *krb5_funcs; +struct acquire_credentials_handle_params +{ + const char *principal; + ULONG credential_use; + const char *username; + const char *password; + LSA_SEC_HANDLE *credential; + ULONG *expiry; +}; + +struct initialize_context_params +{ + LSA_SEC_HANDLE credential; + LSA_SEC_HANDLE context; + const char *target_name; + ULONG context_req; + SecBufferDesc *input; + LSA_SEC_HANDLE *new_context; + SecBufferDesc *output; + ULONG *context_attr; + ULONG *expiry; +}; + +struct make_signature_params +{ + LSA_SEC_HANDLE context; + SecBufferDesc *msg; +}; + +struct query_context_attributes_params +{ + LSA_SEC_HANDLE context; + ULONG attr; + void *buf; +}; + +struct query_ticket_cache_params +{ + KERB_QUERY_TKT_CACHE_RESPONSE *resp; + ULONG *out_size; +}; + +struct seal_message_params +{ + LSA_SEC_HANDLE context; + SecBufferDesc *msg; + ULONG qop; +}; + +struct unseal_message_params +{ + LSA_SEC_HANDLE context; + SecBufferDesc *msg; + ULONG *qop; +}; + +struct verify_signature_params +{ + LSA_SEC_HANDLE context; + SecBufferDesc *msg; + ULONG *qop; +}; + +enum unix_funcs +{ + unix_process_attach, + unix_accept_context, + unix_acquire_credentials_handle, + unix_delete_context, + unix_free_credentials_handle, + unix_initialize_context, + unix_make_signature, + unix_query_context_attributes, + unix_query_ticket_cache, + unix_seal_message, + unix_unseal_message, + unix_verify_signature, +}; + +extern unixlib_handle_t krb5_handle DECLSPEC_HIDDEN; + +#define KRB5_CALL( func, params ) __wine_unix_call( krb5_handle, unix_ ## func, params )