]> git.sur5r.net Git - openldap/commitdiff
ITS#2424 reset SASL on an existing connection
authorHoward Chu <hyc@openldap.org>
Wed, 30 Apr 2003 15:38:32 +0000 (15:38 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 30 Apr 2003 15:38:32 +0000 (15:38 +0000)
include/ldap_pvt.h
libraries/libldap/cyrus.c
servers/slapd/sasl.c

index bf12eea29ad18071f300556e996bd1b81f11929b..602774befb78d814e169d2556a6d2b551da1eb5b 100644 (file)
@@ -170,6 +170,7 @@ LDAP_F (void) ldap_pvt_sasl_mutex_dispose LDAP_P((void *mutex));
 
 struct sockbuf; /* avoid pulling in <lber.h> */
 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 */
index f8e024c6661434885aeb8a5eeeebc2fd4b098ed5..e28da6c09204475b1fbab011cd68ebbbde01e0e7 100644 (file)
@@ -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,
index 789786f3698b7b61ae23a5a9045378ec6088433a..7802516c66df943852d07ecbe47d5bc0e3fcd320 100644 (file)
@@ -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 )