]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/cyrus.c
#include <ac/unistd.h>, to get geteuid() and getegid().
[openldap] / libraries / libldap / cyrus.c
index e28da6c09204475b1fbab011cd68ebbbde01e0e7..1816d8d7c386129a2bb9064c22f59be30265a0cf 100644 (file)
@@ -14,6 +14,7 @@
 #include <ac/time.h>
 #include <ac/errno.h>
 #include <ac/ctype.h>
+#include <ac/unistd.h>
 
 #include "ldap-int.h"
 
@@ -57,22 +58,29 @@ int ldap_int_sasl_init( void )
        };
 
 #ifdef HAVE_SASL_VERSION
-#define SASL_BUILD_VERSION ((SASL_VERSION_MAJOR << 24) |\
-       (SASL_VERSION_MINOR << 16) | SASL_VERSION_STEP)
-
+       /* stringify the version number, sasl.h doesn't do it for us */
+#define VSTR0(maj, min, pat)   #maj "." #min "." #pat
+#define VSTR(maj, min, pat)    VSTR0(maj, min, pat)
+#define SASL_VERSION_STRING    VSTR(SASL_VERSION_MAJOR, SASL_VERSION_MINOR, \
+                               SASL_VERSION_STEP)
        { int rc;
        sasl_version( NULL, &rc );
        if ( ((rc >> 16) != ((SASL_VERSION_MAJOR << 8)|SASL_VERSION_MINOR)) ||
                (rc & 0xffff) < SASL_VERSION_STEP) {
+               char version[sizeof("xxx.xxx.xxxxx")];
+               sprintf( version, "%u.%d.%d", (unsigned)rc >> 24, (rc >> 16) & 0xff,
+                       rc & 0xffff );
 
 #ifdef NEW_LOGGING
                LDAP_LOG( TRANSPORT, INFO,
-               "ldap_int_sasl_init: SASL version mismatch, got %x, wanted %x.\n",
-                       rc, SASL_BUILD_VERSION, 0 );
+               "ldap_int_sasl_init: SASL library version mismatch:"
+               " expected " SASL_VERSION_STRING ","
+               " got %s\n", version, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-               "ldap_int_sasl_init: SASL version mismatch, got %x, wanted %x.\n",
-                       rc, SASL_BUILD_VERSION, 0 );
+               "ldap_int_sasl_init: SASL library version mismatch:"
+               " expected " SASL_VERSION_STRING ","
+               " got %s\n", version, 0, 0 );
 #endif
                return -1;
        }
@@ -146,7 +154,7 @@ sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg )
        }
        sasl_getprop( p->sasl_context, SASL_MAXOUTBUF,
                (SASL_CONST void **) &p->sasl_maxbuf );
-
+           
        sbiod->sbiod_pvt = p;
 
        return 0;
@@ -211,8 +219,8 @@ sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, unsigned max, int debuglevel )
                        sec_buf_in->buf_end, len );
    
        if ( len >= 4 ) {
-               sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base,
-                       max, debuglevel);
+               sec_buf_in->buf_end = sb_sasl_pkt_length(
+                       (unsigned char *) sec_buf_in->buf_base, max, debuglevel);
        }
        else {
                sec_buf_in->buf_end = 0;
@@ -260,7 +268,7 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
        }
 
        /* The new packet always starts at p->sec_buf_in.buf_base */
-       ret = sb_sasl_pkt_length( p->sec_buf_in.buf_base,
+       ret = sb_sasl_pkt_length( (unsigned char *) p->sec_buf_in.buf_base,
                *p->sasl_maxbuf, sbiod->sbiod_sb->sb_debug );
 
        /* Grow the packet buffer if neccessary */
@@ -476,7 +484,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 +512,24 @@ 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 &&
+                       lc->lconn_sasl_authctx != 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 +551,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 +589,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 );
+       oldctx = ld->ld_defconn->lconn_sasl_authctx;
 
-               /* 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 );
@@ -669,7 +673,7 @@ ldap_int_sasl_bind(
        if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
                rc = ld->ld_errno = sasl_err2ldap( saslrc );
 #if SASL_VERSION_MAJOR >= 2
-               ld->ld_error = (char *)sasl_errdetail( ctx );
+               ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) );
 #endif
                goto done;
        }
@@ -757,7 +761,7 @@ ldap_int_sasl_bind(
                if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
                        ld->ld_errno = sasl_err2ldap( saslrc );
 #if SASL_VERSION_MAJOR >= 2
-                       ld->ld_error = (char *)sasl_errdetail( ctx );
+                       ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) );
 #endif
                        rc = ld->ld_errno;
                        goto done;
@@ -768,7 +772,7 @@ ldap_int_sasl_bind(
 
        if ( saslrc != SASL_OK ) {
 #if SASL_VERSION_MAJOR >= 2
-               ld->ld_error = (char *)sasl_errdetail( ctx );
+               ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) );
 #endif
                rc = ld->ld_errno = sasl_err2ldap( saslrc );
                goto done;
@@ -799,9 +803,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 +831,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 +1011,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 +1073,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;