From: Hans Leidekker hans@codeweavers.com
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- libs/ldap/libldap/sasl_w.c | 42 +++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/libs/ldap/libldap/sasl_w.c b/libs/ldap/libldap/sasl_w.c index 2fa09bfd652..88753330fd4 100644 --- a/libs/ldap/libldap/sasl_w.c +++ b/libs/ldap/libldap/sasl_w.c @@ -43,6 +43,7 @@ struct connection unsigned int trailer_size; unsigned int flags; unsigned int qop; + unsigned short package_id; sasl_ssf_t ssf; char *buf; unsigned buf_size; @@ -87,9 +88,17 @@ int sasl_decode( sasl_conn_t *handle, const char *input, unsigned int inputlen, if ((ret = grow_buffer( conn, len )) < 0) return ret; memcpy( conn->buf, input + sizeof(len), len );
- bufs[0].pvBuffer = conn->buf; bufs[0].cbBuffer = len - conn->trailer_size; - bufs[1].pvBuffer = conn->buf + bufs[0].cbBuffer; + if (conn->package_id == RPC_C_AUTHN_GSS_KERBEROS) + { + bufs[0].pvBuffer = conn->buf; + bufs[1].pvBuffer = conn->buf + bufs[0].cbBuffer; + } + else + { + bufs[0].pvBuffer = conn->buf + conn->trailer_size; + bufs[1].pvBuffer = conn->buf; + }
status = DecryptMessage( &conn->ctxt_handle, &buf_desc, 0, NULL ); if (status == SEC_E_OK) @@ -119,9 +128,18 @@ int sasl_encode( sasl_conn_t *handle, const char *input, unsigned int inputlen, ldap_log_printf( NULL, LDAP_DEBUG_TRACE, "sasl_encode: %p,%u\n", input, inputlen );
if ((ret = grow_buffer( conn, sizeof(len) + inputlen + conn->trailer_size )) < 0) return ret; - memcpy( conn->buf + sizeof(len), input, inputlen ); - bufs[0].pvBuffer = conn->buf + sizeof(len); - bufs[1].pvBuffer = conn->buf + sizeof(len) + inputlen; + if (conn->package_id == RPC_C_AUTHN_GSS_KERBEROS) + { + memcpy( conn->buf + sizeof(len), input, inputlen ); + bufs[0].pvBuffer = conn->buf + sizeof(len); + bufs[1].pvBuffer = conn->buf + sizeof(len) + inputlen; + } + else + { + memcpy( conn->buf + sizeof(len) + conn->trailer_size, input, inputlen ); + bufs[0].pvBuffer = conn->buf + sizeof(len) + conn->trailer_size; + bufs[1].pvBuffer = conn->buf + sizeof(len); + }
status = EncryptMessage( &conn->ctxt_handle, (conn->qop & ISC_RET_CONFIDENTIALITY) ? 0 : SECQOP_WRAP_NO_ENCRYPT, &buf_desc, 0 ); if (status == SEC_E_OK) @@ -269,6 +287,18 @@ static ULONG get_trailer_size( CtxtHandle *ctx ) return sizes.cbSecurityTrailer; }
+static unsigned short get_package_id( CtxtHandle *ctx ) +{ + SecPkgContext_NegotiationInfoW info; + unsigned short id; + + memset( &info, 0, sizeof(info) ); + if (QueryContextAttributesW( ctx, SECPKG_ATTR_NEGOTIATION_INFO, &info )) return 0; + id = info.PackageInfo->wRPCID; + FreeContextBuffer( info.PackageInfo ); + return id; +} + int sasl_client_start( sasl_conn_t *handle, const char *mechlist, sasl_interact_t **prompts, const char **clientout, unsigned int *clientoutlen, const char **mech ) { @@ -311,6 +341,7 @@ int sasl_client_start( sasl_conn_t *handle, const char *mechlist, sasl_interact_ { conn->ssf = get_key_size( &conn->ctxt_handle ); conn->trailer_size = get_trailer_size( &conn->ctxt_handle ); + conn->package_id = get_package_id( &conn->ctxt_handle ); return SASL_OK; } } @@ -354,6 +385,7 @@ int sasl_client_step( sasl_conn_t *handle, const char *serverin, unsigned int se
conn->ssf = get_key_size( &conn->ctxt_handle ); conn->trailer_size = get_trailer_size( &conn->ctxt_handle ); + conn->package_id = get_package_id( &conn->ctxt_handle ); conn->qop = attrs; return SASL_OK; }