From 4b73446ab573444097f624b9f01c3873da93e33a Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 30 Apr 2003 15:38:32 +0000 Subject: [PATCH] ITS#2424 reset SASL on an existing connection --- include/ldap_pvt.h | 1 + libraries/libldap/cyrus.c | 21 ++++++++++++++++++++- servers/slapd/sasl.c | 31 ++++++++++++++++++++++++++----- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h index bf12eea29a..602774befb 100644 --- a/include/ldap_pvt.h +++ b/include/ldap_pvt.h @@ -170,6 +170,7 @@ LDAP_F (void) ldap_pvt_sasl_mutex_dispose LDAP_P((void *mutex)); struct sockbuf; /* avoid pulling in */ LDAP_F (int) ldap_pvt_sasl_install LDAP_P(( struct sockbuf *, void * )); +LDAP_F (int) ldap_pvt_sasl_remove LDAP_P(( struct sockbuf * )); #endif /* HAVE_CYRUS_SASL */ #define LDAP_PVT_SASL_LOCAL_SSF 71 /* SSF for Unix Domain Sockets */ diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index f8e024c666..e28da6c092 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -414,6 +414,16 @@ int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg ) return LDAP_SUCCESS; } +void ldap_pvt_sasl_remove( Sockbuf *sb ) +{ + ber_sockbuf_remove_io( sb, &ldap_pvt_sockbuf_io_sasl, + LBER_SBIOD_LEVEL_APPLICATION ); +#ifdef LDAP_DEBUG + ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug, + LBER_SBIOD_LEVEL_APPLICATION ); +#endif +} + static int sasl_err2ldap( int saslerr ) { @@ -569,11 +579,20 @@ ldap_int_sasl_bind( /* 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 */ - rc = ldap_simple_bind_s( ld, "", NULL ); + 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 ); } rc = ldap_int_sasl_open( ld, ld->ld_defconn, diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 789786f369..7802516c66 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -915,6 +915,9 @@ slap_sasl_err2ldap( int saslerr ) int rc; switch (saslerr) { + case SASL_OK: + rc = LDAP_SUCCESS; + break; case SASL_CONTINUE: rc = LDAP_SASL_BIND_IN_PROGRESS; break; @@ -1234,14 +1237,32 @@ int slap_sasl_external( int slap_sasl_reset( Connection *conn ) { -#ifdef HAVE_CYRUS_SASL + int rc = LDAP_SUCCESS; sasl_conn_t *ctx = conn->c_sasl_context; - - if( ctx != NULL ) { + slap_ssf_t ssf = 0; + const char *authid = NULL; +#ifdef HAVE_CYRUS_SASL +#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 - /* must return "anonymous" */ - return LDAP_SUCCESS; + return rc; } char ** slap_sasl_mechs( Connection *conn ) -- 2.39.5