From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kerberos/krb5_ap.c | 27 ++++++++++++++++++++++++--- dlls/kerberos/unixlib.c | 20 ++++++-------------- dlls/kerberos/unixlib.h | 6 ++++-- 3 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/dlls/kerberos/krb5_ap.c b/dlls/kerberos/krb5_ap.c index cc6df975d25..5cc2623c4ad 100644 --- a/dlls/kerberos/krb5_ap.c +++ b/dlls/kerberos/krb5_ap.c @@ -100,6 +100,17 @@ static LSA_SEC_HANDLE create_context_handle( struct context_handle *ctx, UINT64 return (LSA_SEC_HANDLE)ctx; }
+static int get_buffer_index( const SecBufferDesc *desc, DWORD type ) +{ + UINT i; + if (!desc) return -1; + for (i = 0; i < desc->cBuffers; i++) + { + if (desc->pBuffers[i].BufferType == type) return i; + } + return -1; +} + static const char *debugstr_us( const UNICODE_STRING *us ) { if (!us) return "<null>"; @@ -421,6 +432,7 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential { NTSTATUS status = SEC_E_INVALID_HANDLE; ULONG exptime; + int idx;
TRACE( "%Ix, %Ix, %#lx, %lu, %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 ); @@ -430,17 +442,26 @@ static NTSTATUS NTAPI kerberos_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential { struct cred_handle *cred_handle = (struct cred_handle *)credential; struct context_handle *context_handle = (struct context_handle *)context; - struct accept_context_params params; + struct accept_context_params params = { 0 }; UINT64 new_context_handle = 0;
params.credential = cred_handle ? cred_handle->handle : 0; params.context = context_handle ? context_handle->handle : 0; - params.input = input; params.new_context = &new_context_handle; - params.output = output; params.context_attr = context_attr; params.expiry = &exptime;
+ if (input) + { + if ((idx = get_buffer_index( input, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + params.input_token = input->pBuffers[idx].pvBuffer; + params.input_token_length = input->pBuffers[idx].cbBuffer; + } + if ((idx = get_buffer_index( output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + params.output_token = output->pBuffers[idx].pvBuffer; + params.output_token_length = &output->pBuffers[idx].cbBuffer; + + /* FIXME: check if larger output buffer exists */ status = KRB5_CALL( accept_context, ¶ms ); if (!status) { diff --git a/dlls/kerberos/unixlib.c b/dlls/kerberos/unixlib.c index 4d74dd7eb1f..45d8f0b02da 100644 --- a/dlls/kerberos/unixlib.c +++ b/dlls/kerberos/unixlib.c @@ -528,17 +528,9 @@ static NTSTATUS accept_context( void *args ) 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 (!params->input) input_token.length = 0; - else - { - 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( params->output, SECBUFFER_TOKEN )) == -1) return SEC_E_INVALID_TOKEN; + input_token.length = params->input_token_length; + input_token.value = params->input_token; output_token.length = 0; output_token.value = NULL;
@@ -548,16 +540,16 @@ static NTSTATUS accept_context( void *args ) if (GSS_ERROR( ret )) trace_gss_status( ret, minor_status ); if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { - if (output_token.length > params->output->pBuffers[idx].cbBuffer) /* FIXME: check if larger buffer exists */ + if (output_token.length > *params->output_token_length) /* FIXME: check if larger buffer exists */ { TRACE( "buffer too small %lu > %u\n", - (SIZE_T)output_token.length, (unsigned int)params->output->pBuffers[idx].cbBuffer ); + (SIZE_T)output_token.length, (unsigned int)*params->output_token_length ); 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; } - params->output->pBuffers[idx].cbBuffer = output_token.length; - memcpy( params->output->pBuffers[idx].pvBuffer, output_token.value, output_token.length ); + *params->output_token_length = output_token.length; + memcpy( params->output_token, output_token.value, output_token.length ); pgss_release_buffer( &minor_status, &output_token );
ctxhandle_gss_to_sspi( ctx_handle, params->new_context ); diff --git a/dlls/kerberos/unixlib.h b/dlls/kerberos/unixlib.h index 2634182ef51..4fada1e1618 100644 --- a/dlls/kerberos/unixlib.h +++ b/dlls/kerberos/unixlib.h @@ -27,9 +27,11 @@ struct accept_context_params { UINT64 credential; UINT64 context; - SecBufferDesc *input; + BYTE *input_token; + ULONG input_token_length; UINT64 *new_context; - SecBufferDesc *output; + BYTE *output_token; + ULONG *output_token_length; ULONG *context_attr; ULONG *expiry; };