From: Dmitry Timoshkov dmitry@baikal.ru
Partially based on a patch by Hans Leidekker.
Cyrus SALS plugin treats it this way: https://github.com/cyrusimap/cyrus-sasl/blob/master/plugins/gssapi.c
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55304 Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- libs/ldap/libldap/sasl_w.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/libs/ldap/libldap/sasl_w.c b/libs/ldap/libldap/sasl_w.c index 145e14ccdc2..21f15877189 100644 --- a/libs/ldap/libldap/sasl_w.c +++ b/libs/ldap/libldap/sasl_w.c @@ -68,28 +68,41 @@ int sasl_decode( sasl_conn_t *handle, const char *input, unsigned int inputlen, unsigned int len; SecBuffer bufs[2] = { - { conn->trailer_size, SECBUFFER_TOKEN, NULL }, - { inputlen - conn->trailer_size - sizeof(len), SECBUFFER_DATA, NULL } + { 0, SECBUFFER_DATA, NULL }, + { conn->trailer_size, SECBUFFER_TOKEN, NULL } }; SecBufferDesc buf_desc = { SECBUFFER_VERSION, ARRAYSIZE(bufs), bufs }; SECURITY_STATUS status; int ret;
if (inputlen < sizeof(len) + conn->trailer_size) return SASL_FAIL; + len = ntohl( *(unsigned int *)input ); + if (inputlen < sizeof(len) + len) return SASL_FAIL; + + if ((ret = grow_buffer( conn, len )) < 0) return ret; + memcpy( conn->buf, input + sizeof(len), len );
- if ((ret = grow_buffer( conn, inputlen - sizeof(len) )) < 0) return ret; - memcpy( conn->buf, input + sizeof(len), inputlen - sizeof(len) ); - bufs[0].pvBuffer = conn->buf; - bufs[1].pvBuffer = conn->buf + conn->trailer_size; + bufs[0].cbBuffer = len - conn->trailer_size; + 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) { - *output = bufs[1].pvBuffer; - *outputlen = bufs[1].cbBuffer; + *output = bufs[0].pvBuffer; + *outputlen = bufs[0].cbBuffer; + return SASL_OK; }
- return (status == SEC_E_OK) ? SASL_OK : SASL_FAIL; + return SASL_FAIL; }
int sasl_encode( sasl_conn_t *handle, const char *input, unsigned int inputlen, const char **output,