mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-01 04:29:35 -05:00
ITS#2424 use two SASL contexts per session to conform to RFC 2222
This commit is contained in:
parent
0cafb28e31
commit
46e2b97757
8 changed files with 155 additions and 101 deletions
|
|
@ -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;
|
||||
oldctx = ld->ld_defconn->lconn_sasl_authctx;
|
||||
|
||||
/* 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 );
|
||||
|
||||
/* 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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
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;
|
||||
/* 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) {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue