diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c
index e28da6c09204475b1fbab011cd68ebbbde01e0e7..2acfbade17ce7cdbf6be70dc6d77b75ab883aa5f 100644
--- a/libraries/libldap/cyrus.c
+++ b/libraries/libldap/cyrus.c
@@ -476,7 +476,7 @@ ldap_int_sasl_open(
 	int rc;
 	sasl_conn_t *ctx;
 
-	assert( lc->lconn_sasl_ctx == NULL );
+	assert( lc->lconn_sasl_authctx == NULL );
 
 	if ( host == NULL ) {
 		ld->ld_errno = LDAP_LOCAL_ERROR;
@@ -504,18 +504,23 @@ ldap_int_sasl_open(
 		host, 0, 0 );
 #endif
 
-	lc->lconn_sasl_ctx = ctx;
+	lc->lconn_sasl_authctx = ctx;
 
 	return LDAP_SUCCESS;
 }
 
 int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
 {
-	sasl_conn_t *ctx = lc->lconn_sasl_ctx;
+	sasl_conn_t *ctx = lc->lconn_sasl_authctx;
 
 	if( ctx != NULL ) {
 		sasl_dispose( &ctx );
-		lc->lconn_sasl_ctx = NULL;
+		if ( lc->lconn_sasl_sockctx && ctx != lc->lconn_sasl_sockctx ) {
+			ctx = lc->lconn_sasl_sockctx;
+			sasl_dispose( &ctx );
+		}
+		lc->lconn_sasl_sockctx = NULL;
+		lc->lconn_sasl_authctx = NULL;
 	}
 
 	return LDAP_SUCCESS;
@@ -537,7 +542,7 @@ ldap_int_sasl_bind(
 	const char *pmech = NULL;
 	int			saslrc, rc;
 	sasl_ssf_t		*ssf = NULL;
-	sasl_conn_t	*ctx;
+	sasl_conn_t	*ctx, *oldctx = NULL;
 	sasl_interact_t *prompts = NULL;
 	unsigned credlen;
 	struct berval ccred;
@@ -575,33 +580,23 @@ ldap_int_sasl_bind(
 		}
 	}   
 
-	ctx = ld->ld_defconn->lconn_sasl_ctx;
-
-	/* If we already have a context, shut it down */
-	if( ctx ) {
-		int msgid;
-		LDAPMessage *result;
-		/* Do an anonymous bind to kill the server's context */
-		msgid = ldap_simple_bind( ld, "", NULL );
-
-		/* dispose of the old context */
-		ldap_int_sasl_close( ld, ld->ld_defconn );
-		ldap_pvt_sasl_remove( ld->ld_sb );
+	oldctx = ld->ld_defconn->lconn_sasl_authctx;
 
-		/* The reply is sent in the clear, we can't read it
-		 * until after the context and sockbuf are torn down
-		 */
-		rc = ldap_result( ld, msgid, 1, NULL, &result );
-		ldap_msgfree( result );
+	/* If we already have an authentication context, clear it out */
+	if( oldctx ) {
+		if ( oldctx != ld->ld_defconn->lconn_sasl_sockctx ) {
+			sasl_dispose( &oldctx );
+		}
+		ld->ld_defconn->lconn_sasl_authctx = NULL;
 	}
 
 	rc = ldap_int_sasl_open( ld, ld->ld_defconn,
 		ld->ld_defconn->lconn_server->lud_host ?
 		ld->ld_defconn->lconn_server->lud_host : "localhost" );
-		
+
 	if ( rc != LDAP_SUCCESS ) return rc;
 
-	ctx = ld->ld_defconn->lconn_sasl_ctx;
+	ctx = ld->ld_defconn->lconn_sasl_authctx;
 
 	/* Check for TLS */
 	ssl = ldap_pvt_tls_sb_ctx( ld->ld_sb );
@@ -799,9 +794,16 @@ ldap_int_sasl_bind(
 			if( flags != LDAP_SASL_QUIET ) {
 				fprintf( stderr, "SASL installing layers\n" );
 			}
+			if ( ld->ld_defconn->lconn_sasl_sockctx ) {
+				oldctx = ld->ld_defconn->lconn_sasl_sockctx;
+				sasl_dispose( &oldctx );
+				ldap_pvt_sasl_remove( ld->ld_sb );
+			}
 			ldap_pvt_sasl_install( ld->ld_conns->lconn_sb, ctx );
+			ld->ld_defconn->lconn_sasl_sockctx = ctx;
 		}
 	}
+	ld->ld_defconn->lconn_sasl_authctx = ctx;
 
 done:
 	return rc;
@@ -820,7 +822,7 @@ ldap_int_sasl_external(
 	sasl_external_properties_t extprops;
 #endif
 
-	ctx = conn->lconn_sasl_ctx;
+	ctx = conn->lconn_sasl_authctx;
 
 	if ( ctx == NULL ) {
 		return LDAP_LOCAL_ERROR;
@@ -1000,7 +1002,7 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
 				return -1;
 			}
 
-			ctx = ld->ld_defconn->lconn_sasl_ctx;
+			ctx = ld->ld_defconn->lconn_sasl_sockctx;
 
 			if ( ctx == NULL ) {
 				return -1;
@@ -1062,7 +1064,7 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
 			return -1;
 		}
 
-		ctx = ld->ld_defconn->lconn_sasl_ctx;
+		ctx = ld->ld_defconn->lconn_sasl_authctx;
 
 		if ( ctx == NULL ) {
 			return -1;
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index a6f940107cb7265adb074b2df14de63c9e6c8c74..790b72789536db1a1f2eff7524f45c3536ee9e35 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -188,7 +188,8 @@ typedef struct ldap_conn {
    	void		*lconn_tls_ctx;
 #endif
 #ifdef HAVE_CYRUS_SASL
-	void		*lconn_sasl_ctx;
+	void		*lconn_sasl_authctx;	/* context for bind */
+	void		*lconn_sasl_sockctx;	/* for security layer */
 #endif
 	int			lconn_refcnt;
 	time_t		lconn_lastused;	/* time */
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 183337a25d5c601525f88285866125f15c3bc2f7..6598b451ab357446f6ec84e2fa556a0adb62997e 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -693,7 +693,7 @@ be_isroot_pw( Operation *op )
 #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
 	ldap_pvt_thread_mutex_lock( &passwd_mutex );
 #ifdef SLAPD_SPASSWD
-	lutil_passwd_sasl_conn = op->o_conn->c_sasl_context;
+	lutil_passwd_sasl_conn = op->o_conn->c_sasl_authctx;
 #endif
 #endif
 
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index 436a76c5d2cb33948a84b3fceb1107b70aa20d9a..e7b0d29fd14afca2ab25b7a43f22e5d2422182df 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -433,7 +433,9 @@ long connection_init(
 
 		c->c_sasl_bind_mech.bv_val = NULL;
 		c->c_sasl_bind_mech.bv_len = 0;
-		c->c_sasl_context = NULL;
+		c->c_sasl_done = 0;
+		c->c_sasl_authctx = NULL;
+		c->c_sasl_sockctx = NULL;
 		c->c_sasl_extra = NULL;
 		c->c_sasl_bindop = NULL;
 
@@ -467,7 +469,9 @@ long connection_init(
     assert( LDAP_STAILQ_EMPTY(&c->c_ops) );
     assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) );
 	assert( c->c_sasl_bind_mech.bv_val == NULL );
-	assert( c->c_sasl_context == NULL );
+	assert( c->c_sasl_done == 0 );
+	assert( c->c_sasl_authctx == NULL );
+	assert( c->c_sasl_sockctx == NULL );
 	assert( c->c_sasl_extra == NULL );
 	assert( c->c_sasl_bindop == NULL );
 	assert( c->c_currentber == NULL );
@@ -556,7 +560,7 @@ long connection_init(
     }
 #endif
 
-	slap_sasl_open( c );
+	slap_sasl_open( c, 0 );
 	slap_sasl_external( c, ssf, authid );
 
     ldap_pvt_thread_mutex_unlock( &c->c_mutex );
@@ -1241,9 +1245,16 @@ int connection_read(ber_socket_t s)
 
 #ifdef HAVE_CYRUS_SASL
 	if ( c->c_sasl_layers ) {
+		/* If previous layer is not removed yet, give up for now */
+		if ( !c->c_sasl_sockctx ) {
+			connection_return( c );
+			ldap_pvt_thread_mutex_unlock( &connections_mutex );
+			return 0;
+		}
+
 		c->c_sasl_layers = 0;
 
-		rc = ldap_pvt_sasl_install( c->c_sb,  c->c_sasl_context );
+		rc = ldap_pvt_sasl_install( c->c_sb,  c->c_sasl_sockctx );
 
 		if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c
index 10854d5f1fe6edcfb760d0c00a2228d6a4945633..c2e3275a43f40fe03ea6274fabf9e667f82d715e 100644
--- a/servers/slapd/passwd.c
+++ b/servers/slapd/passwd.c
@@ -259,7 +259,7 @@ slap_passwd_check(
 #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
 	ldap_pvt_thread_mutex_lock( &passwd_mutex );
 #ifdef SLAPD_SPASSWD
-	lutil_passwd_sasl_conn = conn->c_sasl_context;
+	lutil_passwd_sasl_conn = conn->c_sasl_authctx;
 #endif
 #endif
 
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 0fc4866e5c281e24f5209b0764492610a9eee75a..711b115023428bab752d71002f20c9c9538f8691 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -834,7 +834,7 @@ LDAP_SLAPD_F (int) slap_sasl_init(void);
 LDAP_SLAPD_F (char *) slap_sasl_secprops( const char * );
 LDAP_SLAPD_F (int) slap_sasl_destroy(void);
 
-LDAP_SLAPD_F (int) slap_sasl_open( Connection *c );
+LDAP_SLAPD_F (int) slap_sasl_open( Connection *c, int reopen );
 LDAP_SLAPD_F (char **) slap_sasl_mechs( Connection *c );
 
 LDAP_SLAPD_F (int) slap_sasl_external( Connection *c,
diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c
index adbaf79a66aeca1a7b9f99b2270ccf6813469a0e..eb8f337cf3a09d7cf0d351f49f76893442b61dd5 100644
--- a/servers/slapd/sasl.c
+++ b/servers/slapd/sasl.c
@@ -825,7 +825,7 @@ slap_sasl_authorize(
 #endif
 
 	/* Figure out how much data we have for the dn */
-	rc = sasl_getprop( conn->c_sasl_context, SASL_REALM, (void **)&realm );
+	rc = sasl_getprop( conn->c_sasl_authctx, SASL_REALM, (void **)&realm );
 	if( rc != SASL_OK && rc != SASL_NOTDONE ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG( TRANSPORT, ERR,
@@ -1047,7 +1047,7 @@ int slap_sasl_destroy( void )
 	return 0;
 }
 
-int slap_sasl_open( Connection *conn )
+int slap_sasl_open( Connection *conn, int reopen )
 {
 	int cb, sc = LDAP_SUCCESS;
 #if SASL_VERSION_MAJOR >= 2
@@ -1058,18 +1058,18 @@ int slap_sasl_open( Connection *conn )
 	sasl_conn_t *ctx = NULL;
 	sasl_callback_t *session_callbacks;
 
-	assert( conn->c_sasl_context == NULL );
-	assert( conn->c_sasl_extra == NULL );
+	assert( conn->c_sasl_authctx == NULL );
 
-	conn->c_sasl_layers = 0;
+	if ( !reopen ) {
+		assert( conn->c_sasl_extra == NULL );
 
-	session_callbacks =
+		session_callbacks =
 #if SASL_VERSION_MAJOR >= 2
-		SLAP_CALLOC( 5, sizeof(sasl_callback_t));
+			SLAP_CALLOC( 5, sizeof(sasl_callback_t));
 #else
-		SLAP_CALLOC( 3, sizeof(sasl_callback_t));
+			SLAP_CALLOC( 3, sizeof(sasl_callback_t));
 #endif
-	if( session_callbacks == NULL ) {
+		if( session_callbacks == NULL ) {
 #ifdef NEW_LOGGING
 			LDAP_LOG( TRANSPORT, ERR, 
 				"slap_sasl_open: SLAP_MALLOC failed", 0, 0, 0 );
@@ -1078,31 +1078,36 @@ int slap_sasl_open( Connection *conn )
 				"slap_sasl_open: SLAP_MALLOC failed", 0, 0, 0 );
 #endif
 			return -1;
-	}
-	conn->c_sasl_extra = session_callbacks;
+		}
+		conn->c_sasl_extra = session_callbacks;
 
-	session_callbacks[cb=0].id = SASL_CB_LOG;
-	session_callbacks[cb].proc = &slap_sasl_log;
-	session_callbacks[cb++].context = conn;
+		session_callbacks[cb=0].id = SASL_CB_LOG;
+		session_callbacks[cb].proc = &slap_sasl_log;
+		session_callbacks[cb++].context = conn;
 
-	session_callbacks[cb].id = SASL_CB_PROXY_POLICY;
-	session_callbacks[cb].proc = &slap_sasl_authorize;
-	session_callbacks[cb++].context = conn;
+		session_callbacks[cb].id = SASL_CB_PROXY_POLICY;
+		session_callbacks[cb].proc = &slap_sasl_authorize;
+		session_callbacks[cb++].context = conn;
 
 #if SASL_VERSION_MAJOR >= 2
-	session_callbacks[cb].id = SASL_CB_CANON_USER;
-	session_callbacks[cb].proc = &slap_sasl_canonicalize;
-	session_callbacks[cb++].context = conn;
-
-	/* XXXX: this should be conditional */
-	session_callbacks[cb].id = SASL_CB_SERVER_USERDB_CHECKPASS;
-	session_callbacks[cb].proc = &slap_sasl_checkpass;
-	session_callbacks[cb++].context = conn;
+		session_callbacks[cb].id = SASL_CB_CANON_USER;
+		session_callbacks[cb].proc = &slap_sasl_canonicalize;
+		session_callbacks[cb++].context = conn;
+
+		/* XXXX: this should be conditional */
+		session_callbacks[cb].id = SASL_CB_SERVER_USERDB_CHECKPASS;
+		session_callbacks[cb].proc = &slap_sasl_checkpass;
+		session_callbacks[cb++].context = conn;
 #endif
 
-	session_callbacks[cb].id = SASL_CB_LIST_END;
-	session_callbacks[cb].proc = NULL;
-	session_callbacks[cb++].context = NULL;
+		session_callbacks[cb].id = SASL_CB_LIST_END;
+		session_callbacks[cb].proc = NULL;
+		session_callbacks[cb++].context = NULL;
+	} else {
+		session_callbacks = conn->c_sasl_extra;
+	}
+
+	conn->c_sasl_layers = 0;
 
 	if( global_host == NULL ) {
 		global_host = ldap_pvt_get_fqdn( NULL );
@@ -1161,7 +1166,7 @@ int slap_sasl_open( Connection *conn )
 		return -1;
 	}
 
-	conn->c_sasl_context = ctx;
+	conn->c_sasl_authctx = ctx;
 
 	if( sc == SASL_OK ) {
 		sc = sasl_setprop( ctx,
@@ -1193,7 +1198,7 @@ int slap_sasl_external(
 {
 #if SASL_VERSION_MAJOR >= 2
 	int sc;
-	sasl_conn_t *ctx = conn->c_sasl_context;
+	sasl_conn_t *ctx = conn->c_sasl_authctx;
 
 	if ( ctx == NULL ) {
 		return LDAP_UNAVAILABLE;
@@ -1213,7 +1218,7 @@ int slap_sasl_external(
 
 #elif defined(HAVE_CYRUS_SASL)
 	int sc;
-	sasl_conn_t *ctx = conn->c_sasl_context;
+	sasl_conn_t *ctx = conn->c_sasl_authctx;
 	sasl_external_properties_t extprops;
 
 	if ( ctx == NULL ) {
@@ -1237,32 +1242,7 @@ int slap_sasl_external(
 
 int slap_sasl_reset( Connection *conn )
 {
-	int rc = LDAP_SUCCESS;
-#ifdef HAVE_CYRUS_SASL
-	sasl_conn_t *ctx = conn->c_sasl_context;
-	slap_ssf_t ssf = 0;
-	const char *authid = NULL;
-#if SASL_VERSION_MAJOR >= 2
-	sasl_getprop( ctx, SASL_SSF_EXTERNAL, &ssf );
-	sasl_getprop( ctx, SASL_AUTH_EXTERNAL, &authid );
-	if ( authid ) authid = ch_strdup( authid );
-#else
-	/* we can't retrieve the external properties from SASL 1.5.
-	 * we can get it again from the underlying TLS or IPC connection,
-	 * but it's simpler just to ignore it since 1.5 is obsolete.
-	 */
-#endif
-	rc = slap_sasl_close( conn );
-	ldap_pvt_sasl_remove( conn->c_sb );
-	if ( rc == LDAP_SUCCESS ) {
-		rc = slap_sasl_open( conn );
-	}
-	if ( rc == LDAP_SUCCESS ) {
-		rc = slap_sasl_external( conn, ssf, authid );
-	}
-	if ( authid ) ch_free( authid );
-#endif
-	return rc;
+	return LDAP_SUCCESS;
 }
 
 char ** slap_sasl_mechs( Connection *conn )
@@ -1270,7 +1250,9 @@ char ** slap_sasl_mechs( Connection *conn )
 	char **mechs = NULL;
 
 #ifdef HAVE_CYRUS_SASL
-	sasl_conn_t *ctx = conn->c_sasl_context;
+	sasl_conn_t *ctx = conn->c_sasl_authctx;
+
+	if( ctx == NULL ) ctx = conn->c_sasl_sockctx;
 
 	if( ctx != NULL ) {
 		int sc;
@@ -1306,13 +1288,19 @@ char ** slap_sasl_mechs( Connection *conn )
 int slap_sasl_close( Connection *conn )
 {
 #ifdef HAVE_CYRUS_SASL
-	sasl_conn_t *ctx = conn->c_sasl_context;
+	sasl_conn_t *ctx = conn->c_sasl_authctx;
 
 	if( ctx != NULL ) {
 		sasl_dispose( &ctx );
 	}
+	if ( conn->c_sasl_sockctx && conn->c_sasl_authctx != conn->c_sasl_sockctx ) {
+		ctx = conn->c_sasl_sockctx;
+		sasl_dispose( &ctx );
+	}
 
-	conn->c_sasl_context = NULL;
+	conn->c_sasl_authctx = NULL;
+	conn->c_sasl_sockctx = NULL;
+	conn->c_sasl_done = 0;
 
 	free( conn->c_sasl_extra );
 	conn->c_sasl_extra = NULL;
@@ -1324,7 +1312,7 @@ int slap_sasl_close( Connection *conn )
 int slap_sasl_bind( Operation *op, SlapReply *rs )
 {
 #ifdef HAVE_CYRUS_SASL
-	sasl_conn_t *ctx = op->o_conn->c_sasl_context;
+	sasl_conn_t *ctx = op->o_conn->c_sasl_authctx;
 	struct berval response;
 	unsigned reslen = 0;
 	int sc;
@@ -1365,6 +1353,30 @@ int slap_sasl_bind( Operation *op, SlapReply *rs )
 #endif
 
 	if ( !op->o_conn->c_sasl_bind_in_progress ) {
+		/* If we already authenticated once, must use a new context */
+		if ( op->o_conn->c_sasl_done ) {
+			slap_ssf_t ssf = 0;
+			const char *authid = NULL;
+#if SASL_VERSION_MAJOR >= 2
+			sasl_getprop( ctx, SASL_SSF_EXTERNAL, (void *)&ssf );
+			sasl_getprop( ctx, SASL_AUTH_EXTERNAL, (void *)&authid );
+			if ( authid ) authid = ch_strdup( authid );
+#endif
+			if ( ctx != op->o_conn->c_sasl_sockctx ) {
+				sasl_dispose( &ctx );
+			}
+			op->o_conn->c_sasl_authctx = NULL;
+				
+			slap_sasl_open( op->o_conn, 1 );
+			ctx = op->o_conn->c_sasl_authctx;
+#if SASL_VERSION_MAJOR >= 2
+			if ( authid ) {
+				sasl_setprop( ctx, SASL_SSF_EXTERNAL, &ssf );
+				sasl_setprop( ctx, SASL_AUTH_EXTERNAL, authid );
+				ch_free( (char *)authid );
+			}
+#endif
+		}
 		sc = START( ctx,
 			op->o_conn->c_sasl_bind_mech.bv_val,
 			op->orb_cred.bv_val, op->orb_cred.bv_len,
@@ -1384,21 +1396,47 @@ int slap_sasl_bind( Operation *op, SlapReply *rs )
 		op->orb_edn = op->o_conn->c_sasl_dn;
 		op->o_conn->c_sasl_dn.bv_val = NULL;
 		op->o_conn->c_sasl_dn.bv_len = 0;
+		op->o_conn->c_sasl_done = 1;
 
 		rs->sr_err = LDAP_SUCCESS;
 
 		(void) sasl_getprop( ctx, SASL_SSF, (void *)&ssf );
 		op->orb_ssf = ssf ? *ssf : 0;
 
+		ctx = NULL;
 		if( op->orb_ssf ) {
 			ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 			op->o_conn->c_sasl_layers++;
+
+			/* If there's an old layer, set sockctx to NULL to
+			 * tell connection_read() to wait for us to finish.
+			 * Otherwise there is a race condition: we have to
+			 * send the Bind response using the old security
+			 * context and then remove it before reading any
+			 * new messages.
+			 */
+			if ( op->o_conn->c_sasl_sockctx ) {
+				ctx = op->o_conn->c_sasl_sockctx;
+				op->o_conn->c_sasl_sockctx = NULL;
+			} else {
+				op->o_conn->c_sasl_sockctx = op->o_conn->c_sasl_authctx;
+			}
 			ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 		}
 
+		/* Must send response using old security layer */
 		if (response.bv_len) rs->sr_sasldata = &response;
 		send_ldap_sasl( op, rs );
-
+		
+		/* Now dispose of the old security layer.
+		 */
+		if ( ctx ) {
+			ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+			ldap_pvt_sasl_remove( op->o_conn->c_sb );
+			op->o_conn->c_sasl_sockctx = op->o_conn->c_sasl_authctx;
+			ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+			sasl_dispose( &ctx );
+		}
 	} else if ( sc == SASL_CONTINUE ) {
 		rs->sr_err = LDAP_SASL_BIND_IN_PROGRESS,
 		rs->sr_sasldata = &response;
@@ -1454,7 +1492,7 @@ slap_sasl_setpass( Operation *op, SlapReply *rs )
 
 	assert( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) == 0 );
 
-	rs->sr_err = sasl_getprop( op->o_conn->c_sasl_context, SASL_USERNAME,
+	rs->sr_err = sasl_getprop( op->o_conn->c_sasl_authctx, SASL_USERNAME,
 		(SASL_CONST void **)&id.bv_val );
 
 	if( rs->sr_err != SASL_OK ) {
@@ -1492,13 +1530,13 @@ slap_sasl_setpass( Operation *op, SlapReply *rs )
 	}
 
 #if SASL_VERSION_MAJOR < 2
-	rs->sr_err = sasl_setpass( op->o_conn->c_sasl_context,
+	rs->sr_err = sasl_setpass( op->o_conn->c_sasl_authctx,
 		id.bv_val, new.bv_val, new.bv_len, 0, &rs->sr_text );
 #else
-	rs->sr_err = sasl_setpass( op->o_conn->c_sasl_context, id.bv_val,
+	rs->sr_err = sasl_setpass( op->o_conn->c_sasl_authctx, id.bv_val,
 		new.bv_val, new.bv_len, old.bv_val, old.bv_len, 0 );
 	if( rs->sr_err != SASL_OK ) {
-		rs->sr_text = sasl_errdetail( op->o_conn->c_sasl_context );
+		rs->sr_text = sasl_errdetail( op->o_conn->c_sasl_authctx );
 	}
 #endif
 	switch(rs->sr_err) {
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index d27dec4be9aa65a92fb5b393de9fe320a9b610ed..918e193e9679affe443852b188a0aee3e62e1bdf 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -2068,7 +2068,9 @@ typedef struct slap_conn {
 	int	c_needs_tls_accept;	/* true if SSL_accept should be called */
 #endif
 	int		c_sasl_layers;	 /* true if we need to install SASL i/o handlers */
-	void	*c_sasl_context;	/* SASL session context */
+	int	c_sasl_done;		/* SASL completed once */
+	void	*c_sasl_authctx;	/* SASL authentication context */
+	void	*c_sasl_sockctx;	/* SASL security layer context */
 	void	*c_sasl_extra;		/* SASL session extra stuff */
 	struct slap_op	*c_sasl_bindop;	/* set to current op if it's a bind */