diff --git a/cyrus-sasl-2.1.26-gssapi-lock.patch b/cyrus-sasl-2.1.26-gssapi-lock.patch new file mode 100644 index 0000000..26e1c39 --- /dev/null +++ b/cyrus-sasl-2.1.26-gssapi-lock.patch @@ -0,0 +1,699 @@ +From 4a64c00dba4d35cadc71242f9f81336f46f72009 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 4 Dec 2015 17:59:26 +0100 +Subject: [PATCH] GSSAPI: Use per-connection mutex where possible + + Original patch from Alexander Bokovoy +--- + plugins/gssapi.c | 225 +++++++++++++++++++++++++++++++------------------------ + 1 file changed, 126 insertions(+), 99 deletions(-) + +diff --git a/plugins/gssapi.c b/plugins/gssapi.c +index 60cc38c..50e1217 100644 +--- a/plugins/gssapi.c ++++ b/plugins/gssapi.c +@@ -126,20 +126,29 @@ extern gss_OID gss_nt_service_name; + */ + + #ifdef GSS_USE_MUTEXES +-#define GSS_LOCK_MUTEX(utils) \ +- if(((sasl_utils_t *)(utils))->mutex_lock(gss_mutex) != 0) { \ ++#define GSS_LOCK_MUTEX_EXT(utils, mutex) \ ++ if(((sasl_utils_t *)(utils))->mutex_lock(mutex) != 0) { \ + return SASL_FAIL; \ + } + +-#define GSS_UNLOCK_MUTEX(utils) \ +- if(((sasl_utils_t *)(utils))->mutex_unlock(gss_mutex) != 0) { \ ++#define GSS_UNLOCK_MUTEX_EXT(utils, mutex) \ ++ if(((sasl_utils_t *)(utils))->mutex_unlock(mutex) != 0) { \ + return SASL_FAIL; \ + } + ++#define GSS_LOCK_MUTEX(utils) GSS_LOCK_MUTEX_EXT(utils, gss_mutex) ++#define GSS_UNLOCK_MUTEX(utils) GSS_UNLOCK_MUTEX_EXT(utils, gss_mutex) ++ ++#define GSS_LOCK_MUTEX_CTX(utils, ctx) GSS_LOCK_MUTEX_EXT(utils, (ctx)->ctx_mutex) ++#define GSS_UNLOCK_MUTEX_CTX(utils, ctx) GSS_UNLOCK_MUTEX_EXT(utils, (ctx)->ctx_mutex) ++ ++ + static void *gss_mutex = NULL; + #else + #define GSS_LOCK_MUTEX(utils) + #define GSS_UNLOCK_MUTEX(utils) ++#define GSS_LOCK_MUTEX_CTX(utils, ctx) ++#define GSS_UNLOCK_MUTEX_CTX(utils, ctx) + #endif + + typedef struct context { +@@ -176,6 +185,7 @@ typedef struct context { + + char *authid; /* hold the authid between steps - server */ + const char *user; /* hold the userid between steps - client */ ++ void *ctx_mutex; /* A per-context mutex */ + } context_t; + + enum { +@@ -355,7 +365,7 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov, + output_token->value = NULL; + output_token->length = 0; + +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + maj_stat = gss_wrap (&min_stat, + text->gss_ctx, + privacy, +@@ -363,14 +373,14 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov, + input_token, + NULL, + output_token); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + } + return SASL_FAIL; + } +@@ -384,9 +394,9 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov, + output_token->length + 4); + + if (ret != SASL_OK) { +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + return ret; + } + +@@ -407,9 +417,9 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov, + *output = text->encode_buf; + + if (output_token->value) { +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + } + + return SASL_OK; +@@ -455,21 +465,21 @@ gssapi_decode_packet(void *context, + output_token->value = NULL; + output_token->length = 0; + +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + maj_stat = gss_unwrap (&min_stat, + text->gss_ctx, + input_token, + output_token, + NULL, + NULL); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils,maj_stat,min_stat); + if (output_token->value) { +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + } + return SASL_FAIL; + } +@@ -484,17 +494,17 @@ gssapi_decode_packet(void *context, + &text->decode_once_buf_len, + *outputlen); + if (result != SASL_OK) { +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + return result; + } + *output = text->decode_once_buf; + memcpy(*output, output_token->value, *outputlen); + } +- GSS_LOCK_MUTEX(text->utils); ++ GSS_LOCK_MUTEX_CTX(text->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(text->utils); ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); + } + + return SASL_OK; +@@ -525,7 +535,14 @@ static context_t *sasl_gss_new_context(const sasl_utils_t *utils) + + memset(ret,0,sizeof(context_t)); + ret->utils = utils; +- ++#ifdef GSS_USE_MUTEXES ++ ret->ctx_mutex = utils->mutex_alloc(); ++ if (!ret->ctx_mutex) { ++ utils->free(ret); ++ return NULL; ++ } ++#endif ++ + return ret; + } + +@@ -535,7 +552,11 @@ static int sasl_gss_free_context_contents(context_t *text) + + if (!text) return SASL_OK; + +- GSS_LOCK_MUTEX(text->utils); ++#ifdef GSS_USE_MUTEXES ++ if (text->ctx_mutex) { ++ GSS_LOCK_MUTEX_CTX(text->utils, text); ++ } ++#endif + + if (text->gss_ctx != GSS_C_NO_CONTEXT) { + maj_stat = gss_delete_sec_context(&min_stat,&text->gss_ctx, +@@ -563,8 +584,6 @@ static int sasl_gss_free_context_contents(context_t *text) + text->client_creds = GSS_C_NO_CREDENTIAL; + } + +- GSS_UNLOCK_MUTEX(text->utils); +- + if (text->out_buf) { + text->utils->free(text->out_buf); + text->out_buf = NULL; +@@ -598,6 +617,14 @@ static int sasl_gss_free_context_contents(context_t *text) + text->authid = NULL; + } + ++#ifdef GSS_USE_MUTEXES ++ if (text->ctx_mutex) { ++ GSS_UNLOCK_MUTEX_CTX(text->utils, text); ++ text->utils->mutex_free(text->ctx_mutex); ++ text->ctx_mutex = NULL; ++ } ++#endif ++ + return SASL_OK; + + } +@@ -692,12 +719,12 @@ gssapi_server_mech_authneg(context_t *text, + } + sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN); + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_HOSTBASED_SERVICE, + &text->server_name); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + params->utils->free(name_token.value); + name_token.value = NULL; +@@ -709,15 +736,15 @@ gssapi_server_mech_authneg(context_t *text, + } + + if ( text->server_creds != GSS_C_NO_CREDENTIAL) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_release_cred(&min_stat, &text->server_creds); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + text->server_creds = GSS_C_NO_CREDENTIAL; + } + + /* If caller didn't provide creds already */ + if ( server_creds == GSS_C_NO_CREDENTIAL) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_acquire_cred(&min_stat, + text->server_name, + GSS_C_INDEFINITE, +@@ -726,7 +753,7 @@ gssapi_server_mech_authneg(context_t *text, + &text->server_creds, + NULL, + NULL); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); +@@ -743,7 +770,7 @@ gssapi_server_mech_authneg(context_t *text, + } + + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = + gss_accept_sec_context(&min_stat, + &(text->gss_ctx), +@@ -756,15 +783,15 @@ gssapi_server_mech_authneg(context_t *text, + &out_flags, + NULL, /* context validity period */ + &(text->client_creds)); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_log(text->utils, maj_stat, min_stat); + text->utils->seterror(text->utils->conn, SASL_NOLOG, "GSSAPI Failure: gss_accept_sec_context"); + if (output_token->value) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + sasl_gss_free_context_contents(text); + return SASL_BADAUTH; +@@ -778,18 +805,18 @@ gssapi_server_mech_authneg(context_t *text, + ret = _plug_buf_alloc(text->utils, &(text->out_buf), + &(text->out_buf_len), *serveroutlen); + if(ret != SASL_OK) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + return ret; + } + memcpy(text->out_buf, output_token->value, *serveroutlen); + *serverout = text->out_buf; + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } else { + /* No output token, send an empty string */ + *serverout = GSSAPI_BLANK_STRING; +@@ -832,12 +859,12 @@ gssapi_server_mech_authneg(context_t *text, + /* continue with authentication */ + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_canonicalize_name(&min_stat, + text->client_name, + mech_type, + &client_name_MN); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_canonicalize_name"); +@@ -848,12 +875,12 @@ gssapi_server_mech_authneg(context_t *text, + name_token.value = NULL; + name_without_realm.value = NULL; + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_display_name (&min_stat, + client_name_MN, + &name_token, + NULL); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_display_name"); +@@ -883,7 +910,7 @@ gssapi_server_mech_authneg(context_t *text, + + name_without_realm.length = strlen( (char *) name_without_realm.value ); + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_import_name (&min_stat, + &name_without_realm, + /* Solaris 8/9 gss_import_name doesn't accept GSS_C_NULL_OID here, +@@ -894,7 +921,7 @@ gssapi_server_mech_authneg(context_t *text, + GSS_C_NULL_OID, + #endif + &without); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_import_name"); +@@ -903,12 +930,12 @@ gssapi_server_mech_authneg(context_t *text, + goto cleanup; + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_compare_name(&min_stat, + client_name_MN, + without, + &equal); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_compare_name"); +@@ -1059,7 +1086,7 @@ gssapi_server_mech_ssfcap(context_t *text, + real_input_token.value = (void *)sasldata; + real_input_token.length = 4; + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_wrap(&min_stat, + text->gss_ctx, + 0, /* Just integrity checking here */ +@@ -1067,14 +1094,14 @@ gssapi_server_mech_ssfcap(context_t *text, + input_token, + NULL, + output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; +@@ -1088,18 +1115,18 @@ gssapi_server_mech_ssfcap(context_t *text, + ret = _plug_buf_alloc(text->utils, &(text->out_buf), + &(text->out_buf_len), *serveroutlen); + if(ret != SASL_OK) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + return ret; + } + memcpy(text->out_buf, output_token->value, *serveroutlen); + *serverout = text->out_buf; + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + + /* Wait for ssf request and authid */ +@@ -1130,14 +1157,14 @@ gssapi_server_mech_ssfreq(context_t *text, + real_input_token.value = (void *)clientin; + real_input_token.length = clientinlen; + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_unwrap(&min_stat, + text->gss_ctx, + input_token, + output_token, + NULL, + NULL); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); +@@ -1148,9 +1175,9 @@ gssapi_server_mech_ssfreq(context_t *text, + if (output_token->length < 4) { + SETERROR(text->utils, + "token too short"); +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } +@@ -1181,9 +1208,9 @@ gssapi_server_mech_ssfreq(context_t *text, + /* Mark that we attempted negotiation */ + oparams->mech_ssf = 2; + if (output_token->value) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; +@@ -1227,9 +1254,9 @@ gssapi_server_mech_ssfreq(context_t *text, + } + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; + +@@ -1553,12 +1580,12 @@ static int gssapi_client_mech_step(void *conn_context, + + sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN); + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_HOSTBASED_SERVICE, + &text->server_name); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + params->utils->free(name_token.value); + name_token.value = NULL; +@@ -1582,9 +1609,9 @@ static int gssapi_client_mech_step(void *conn_context, + * and no input from the server. However, thanks to Imap, + * which discards our first output, this happens all the time. + * Throw away the context and try again. */ +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_delete_sec_context (&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + text->gss_ctx = GSS_C_NO_CONTEXT; + } + +@@ -1606,7 +1633,7 @@ static int gssapi_client_mech_step(void *conn_context, + req_flags = req_flags | GSS_C_DELEG_FLAG; + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_init_sec_context(&min_stat, + client_creds, /* GSS_C_NO_CREDENTIAL */ + &text->gss_ctx, +@@ -1620,14 +1647,14 @@ static int gssapi_client_mech_step(void *conn_context, + output_token, + &out_req_flags, + NULL); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; +@@ -1658,22 +1685,22 @@ static int gssapi_client_mech_step(void *conn_context, + ret = _plug_buf_alloc(text->utils, &(text->out_buf), + &(text->out_buf_len), *clientoutlen); + if(ret != SASL_OK) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + return ret; + } + memcpy(text->out_buf, output_token->value, *clientoutlen); + *clientout = text->out_buf; + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + + if (maj_stat == GSS_S_COMPLETE) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_inquire_context(&min_stat, + text->gss_ctx, + &text->client_name, +@@ -1684,7 +1711,7 @@ static int gssapi_client_mech_step(void *conn_context, + NULL, /* flags */ + NULL, /* local init */ + NULL); /* open */ +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); +@@ -1693,18 +1720,18 @@ static int gssapi_client_mech_step(void *conn_context, + } + + name_token.length = 0; +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_display_name(&min_stat, + text->client_name, + &name_token, + NULL); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + if (name_token.value) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, &name_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + SETERROR(text->utils, "GSSAPI Failure"); + sasl_gss_free_context_contents(text); +@@ -1725,9 +1752,9 @@ static int gssapi_client_mech_step(void *conn_context, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + oparams); + } +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, &name_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (ret != SASL_OK) return ret; + +@@ -1753,32 +1780,32 @@ static int gssapi_client_mech_step(void *conn_context, + real_input_token.value = (void *) serverin; + real_input_token.length = serverinlen; + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_unwrap(&min_stat, + text->gss_ctx, + input_token, + output_token, + NULL, + NULL); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); +- sasl_gss_free_context_contents(text); + if (output_token->value) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } ++ sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + if (output_token->length != 4) { + SETERROR(text->utils, + (output_token->length < 4) ? "token too short" : "token too long"); +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } +@@ -1879,9 +1906,9 @@ static int gssapi_client_mech_step(void *conn_context, + } + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + /* oparams->user is always set, due to canon_user requirements. + * Make sure the client actually requested it though, by checking +@@ -1927,7 +1954,7 @@ static int gssapi_client_mech_step(void *conn_context, + } + ((unsigned char *)input_token->value)[0] = mychoice; + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_wrap (&min_stat, + text->gss_ctx, + 0, /* Just integrity checking here */ +@@ -1935,7 +1962,7 @@ static int gssapi_client_mech_step(void *conn_context, + input_token, + NULL, + output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + params->utils->free(input_token->value); + input_token->value = NULL; +@@ -1943,9 +1970,9 @@ static int gssapi_client_mech_step(void *conn_context, + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; +@@ -1961,18 +1988,18 @@ static int gssapi_client_mech_step(void *conn_context, + &(text->out_buf_len), + *clientoutlen); + if (ret != SASL_OK) { +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + return ret; + } + memcpy(text->out_buf, output_token->value, *clientoutlen); + *clientout = text->out_buf; + } + +- GSS_LOCK_MUTEX(params->utils); ++ GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); +- GSS_UNLOCK_MUTEX(params->utils); ++ GSS_UNLOCK_MUTEX_CTX(params->utils, text); + + } + diff --git a/cyrus-sasl-2.1.26-ssf-from-gssapi.patch b/cyrus-sasl-2.1.26-ssf-from-gssapi.patch index 73bf27f..097f4f1 100644 --- a/cyrus-sasl-2.1.26-ssf-from-gssapi.patch +++ b/cyrus-sasl-2.1.26-ssf-from-gssapi.patch @@ -158,9 +158,9 @@ index 3050962..348debe 100644 - } - } - - GSS_LOCK_MUTEX(params->utils); + GSS_LOCK_MUTEX_CTX(params->utils, text); gss_release_buffer(&min_stat, output_token); - GSS_UNLOCK_MUTEX(params->utils); + GSS_UNLOCK_MUTEX_CTX(params->utils, text); + if (oparams->mech_ssf) { + int ret; @@ -204,9 +204,9 @@ index 3050962..348debe 100644 - } - } - - GSS_LOCK_MUTEX(params->utils); + GSS_LOCK_MUTEX_CTX(params->utils, text); gss_release_buffer(&min_stat, output_token); - GSS_UNLOCK_MUTEX(params->utils); + GSS_UNLOCK_MUTEX_CTX(params->utils, text); - + + if (oparams->mech_ssf) { diff --git a/cyrus-sasl.spec b/cyrus-sasl.spec index 1cda291..70ec34b 100644 --- a/cyrus-sasl.spec +++ b/cyrus-sasl.spec @@ -63,8 +63,10 @@ Patch56: cyrus-sasl-2.1.26-user-specified-logging.patch Patch57: cyrus-sasl-2.1.27-openssl-1.1.0.patch # Fix support for GSS SPNEGO to be compatible with windows (#1421663) Patch58: cyrus-sasl-2.1.26-gss-spnego.patch +# Use per-connection mutex where possible +Patch59: cyrus-sasl-2.1.26-gssapi-lock.patch # Allow cyrus sasl to get the ssf from gssapi #429 -Patch59: cyrus-sasl-2.1.26-ssf-from-gssapi.patch +Patch60: cyrus-sasl-2.1.26-ssf-from-gssapi.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, automake, libtool, gdbm-devel, groff @@ -215,7 +217,8 @@ chmod -x include/*.h %patch56 -p1 -b .too-much-logging %patch57 -p1 -b .openssl110 %patch58 -p1 -b .spnego -%patch59 -p1 -b .ssf-gssapi +%patch59 -p1 -b .mutex +%patch60 -p1 -b .ssf-gssapi %build