]> git.sur5r.net Git - openldap/commitdiff
ITS#2424 use two SASL contexts per session to conform to RFC 2222
authorHoward Chu <hyc@openldap.org>
Thu, 1 May 2003 04:11:57 +0000 (04:11 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 1 May 2003 04:11:57 +0000 (04:11 +0000)
libraries/libldap/cyrus.c
libraries/libldap/ldap-int.h
servers/slapd/backend.c
servers/slapd/connection.c
servers/slapd/passwd.c
servers/slapd/proto-slap.h
servers/slapd/sasl.c
servers/slapd/slap.h

index e28da6c09204475b1fbab011cd68ebbbde01e0e7..2acfbade17ce7cdbf6be70dc6d77b75ab883aa5f 100644 (file)
@@ -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;
index a6f940107cb7265adb074b2df14de63c9e6c8c74..790b72789536db1a1f2eff7524f45c3536ee9e35 100644 (file)
@@ -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 */
index 183337a25d5c601525f88285866125f15c3bc2f7..6598b451ab357446f6ec84e2fa556a0adb62997e 100644 (file)
@@ -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
 
index 436a76c5d2cb33948a84b3fceb1107b70aa20d9a..e7b0d29fd14afca2ab25b7a43f22e5d2422182df 100644 (file)
@@ -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
index 10854d5f1fe6edcfb760d0c00a2228d6a4945633..c2e3275a43f40fe03ea6274fabf9e667f82d715e 100644 (file)
@@ -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
 
index 0fc4866e5c281e24f5209b0764492610a9eee75a..711b115023428bab752d71002f20c9c9538f8691 100644 (file)
@@ -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,
index adbaf79a66aeca1a7b9f99b2270ccf6813469a0e..eb8f337cf3a09d7cf0d351f49f76893442b61dd5 100644 (file)
@@ -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) {
index d27dec4be9aa65a92fb5b393de9fe320a9b610ed..918e193e9679affe443852b188a0aee3e62e1bdf 100644 (file)
@@ -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 */