diff --git a/SOURCES/cyrus-sasl-2.1.26-gssapi-use-per-connection-mutex.patch b/SOURCES/cyrus-sasl-2.1.26-gssapi-use-per-connection-mutex.patch
new file mode 100644
index 0000000..1b3278b
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.26-gssapi-use-per-connection-mutex.patch
@@ -0,0 +1,710 @@
+From 70a144cc53d09b56aa088fa1f6d433acea31afa7 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Tue, 15 Sep 2015 12:21:22 +0300
+Subject: [PATCH] gssapi: use per-connection mutex where possible
+
+If the same application uses SASL GSSAPI for both client and server operations,
+it may be possible to deadlock in plugins/gssapi.c due to use of a
+global mutex by both client and server code. Multiple outstanding connections should
+be possible, thus introduce per-context locking and use it where it
+makes sense. Note that there are still multiple places where context is
+not available and where a global lock should be in use.
+
+Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1263017
+---
+ plugins/gssapi.c | 225 +++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 126 insertions(+), 99 deletions(-)
+
+diff --git a/plugins/gssapi.c b/plugins/gssapi.c
+index 2fd1b3b..f5d3354 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");
+@@ -1053,7 +1080,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 */
+@@ -1061,14 +1088,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;
+@@ -1082,18 +1109,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 */
+@@ -1124,14 +1151,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);
+@@ -1142,9 +1169,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;
+     }
+@@ -1175,9 +1202,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;
+@@ -1221,9 +1248,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;
+ 
+@@ -1547,12 +1574,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;
+@@ -1576,9 +1603,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;
+ 	}
+ 
+@@ -1600,7 +1627,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,
+@@ -1614,14 +1641,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;
+@@ -1652,22 +1679,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,
+@@ -1678,7 +1705,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);
+@@ -1687,18 +1714,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);
+@@ -1719,9 +1746,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;
+ 	    
+@@ -1747,32 +1774,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;
+ 	}
+@@ -1873,9 +1900,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
+@@ -1921,7 +1948,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 */
+@@ -1929,7 +1956,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;
+@@ -1937,9 +1964,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;
+@@ -1955,18 +1982,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);
+ 
+ 	}
+ 	
+-- 
+2.4.3
+
+
diff --git a/SPECS/cyrus-sasl.spec b/SPECS/cyrus-sasl.spec
index 62f90f6..2124c7f 100644
--- a/SPECS/cyrus-sasl.spec
+++ b/SPECS/cyrus-sasl.spec
@@ -10,7 +10,7 @@
 Summary: The Cyrus SASL library
 Name: cyrus-sasl
 Version: 2.1.26
-Release: 19.2%{?dist}
+Release: 20%{?dist}
 License: BSD with advertising
 Group: System Environment/Libraries
 # Source0 originally comes from ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/;
@@ -62,6 +62,8 @@ Patch55: cyrus-sasl-2.1.26-make-client-thread-sage.patch
 Patch56: cyrus-sasl-2.1.26-handle-single-character-mechanisms.patch
 # Fix confusing message when config file has typo (#1022479)
 Patch57: cyrus-sasl-2.1.26-error-message-when-config-has-typo.patch
+# GSSAPI: Use per-connection mutex where possible (#1263017)
+Patch58: cyrus-sasl-2.1.26-gssapi-use-per-connection-mutex.patch
 
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
@@ -211,6 +213,7 @@ chmod -x include/*.h
 %patch55 -p1 -b .threads
 %patch56 -p1 -b .prefix
 %patch57 -p1 -b .typo
+%patch58 -p1 -b .mutex
 
 
 %build
@@ -434,6 +437,9 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} 
 %{_sbindir}/sasl2-shared-mechlist
 
 %changelog
+* Fri Dec 04 2015 Jakub Jelen <jjelen@redhat.com> 2.1.26-20
+- GSSAPI: Use per-connection mutex where possible (#1263017)
+
 * Thu Jul 16 2015 Jakub Jelen <jjelen@redhat.com> 2.1.26-19.2
 - Revert tmpfiles.d and use new systemd feature RuntimeDirectory (#1188065)