X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fcyrus.c;h=5f128098d353f079f95da282ee06beb5c46ecb95;hb=b0b8546f054f31b1a080defede171f833d20b124;hp=c72198b40737bee2d6256a4b29798a1546a04f78;hpb=599a61016423e4ea98363a827e3d1bdd8e88600e;p=openldap diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index c72198b407..5f128098d3 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -1,27 +1,39 @@ /* $OpenLDAP$ */ /* - * Copyright 1999-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1999-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ #include "portable.h" -#include #include #include +#include #include #include #include #include #include "ldap-int.h" + +#ifdef HAVE_CYRUS_SASL + #ifdef LDAP_R_COMPILE -#include "ldap_pvt_thread.h" +ldap_pvt_thread_mutex_t ldap_int_sasl_mutex; #endif -#ifdef HAVE_CYRUS_SASL +#ifdef HAVE_SASL_SASL_H +#include +#else #include +#endif + +#if SASL_VERSION_MAJOR >= 2 +#define SASL_CONST const +#else +#define SASL_CONST +#endif /* * Various Cyrus SASL related stuff. @@ -62,6 +74,8 @@ int ldap_int_sasl_init( void ) ldap_pvt_sasl_mutex_lock, ldap_pvt_sasl_mutex_unlock, ldap_pvt_sasl_mutex_dispose ); + + ldap_pvt_thread_mutex_init( &ldap_int_sasl_mutex ); #endif if ( sasl_client_init( client_callbacks ) == SASL_OK ) { @@ -115,6 +129,14 @@ sb_sasl_remove( Sockbuf_IO_Desc *sbiod ) assert( sbiod != NULL ); p = (struct sb_sasl_data *)sbiod->sbiod_pvt; +#if SASL_VERSION_MAJOR >= 2 + /* + * SASLv2 encode/decode buffers are managed by + * libsasl2. Ensure they are not freed by liblber. + */ + p->buf_in.buf_base = NULL; + p->buf_out.buf_base = NULL; +#endif ber_pvt_sb_buf_destroy( &p->sec_buf_in ); ber_pvt_sb_buf_destroy( &p->buf_in ); ber_pvt_sb_buf_destroy( &p->buf_out ); @@ -124,15 +146,16 @@ sb_sasl_remove( Sockbuf_IO_Desc *sbiod ) } static ber_len_t -sb_sasl_pkt_length( const char *buf, int debuglevel ) +sb_sasl_pkt_length( const unsigned char *buf, int debuglevel ) { ber_len_t size; - long tmp; assert( buf != NULL ); - tmp = *((long *)buf); - size = ntohl( tmp ); + size = buf[0] << 24 + | buf[1] << 16 + | buf[2] << 8 + | buf[3]; /* we really should check against actual buffer size set * in the secopts. @@ -156,7 +179,7 @@ sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel ) len = sec_buf_in->buf_ptr - sec_buf_in->buf_end; if ( len > 0 ) - memmove( sec_buf_in->buf_base, sec_buf_in->buf_base + + AC_MEMCPY( sec_buf_in->buf_base, sec_buf_in->buf_base + sec_buf_in->buf_end, len ); if ( len >= 4 ) { @@ -188,7 +211,11 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) if ( len == 0 ) return bufptr; +#if SASL_VERSION_MAJOR >= 2 + ber_pvt_sb_buf_init( &p->buf_in ); +#else ber_pvt_sb_buf_destroy( &p->buf_in ); +#endif /* Read the length of the packet */ while ( p->sec_buf_in.buf_ptr < 4 ) { @@ -209,7 +236,7 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) sbiod->sbiod_sb->sb_debug ); /* Grow the packet buffer if neccessary */ - if ( ( p->sec_buf_in.buf_size < ret ) && + if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) && ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) { errno = ENOMEM; @@ -236,7 +263,8 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) /* Decode the packet */ ret = sasl_decode( p->sasl_context, p->sec_buf_in.buf_base, - p->sec_buf_in.buf_end, &p->buf_in.buf_base, + p->sec_buf_in.buf_end, + (SASL_CONST char **)&p->buf_in.buf_base, (unsigned *)&p->buf_in.buf_end ); if ( ret != SASL_OK ) { ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug, @@ -277,8 +305,13 @@ sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) } /* now encode the next packet. */ +#if SASL_VERSION_MAJOR >= 2 + ber_pvt_sb_buf_init( &p->buf_out ); +#else ber_pvt_sb_buf_destroy( &p->buf_out ); - ret = sasl_encode( p->sasl_context, buf, len, &p->buf_out.buf_base, +#endif + ret = sasl_encode( p->sasl_context, buf, len, + (SASL_CONST char **)&p->buf_out.buf_base, (unsigned *)&p->buf_out.buf_size ); if ( ret != SASL_OK ) { ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug, @@ -320,8 +353,12 @@ Sockbuf_IO ldap_pvt_sockbuf_io_sasl = { int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg ) { +#ifdef NEW_LOGGING + LDAP_LOG (( "cyrus", LDAP_LEVEL_ENTRY, "ldap_pvt_sasl_install\n" )); +#else Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_install\n", 0, 0, 0 ); +#endif /* don't install the stuff unless security has been negotiated */ @@ -393,7 +430,7 @@ ldap_int_sasl_open( sasl_conn_t *ctx; sasl_callback_t *session_callbacks = - ber_memcalloc( 2, sizeof( sasl_callback_t ) ); + LDAP_CALLOC( 2, sizeof( sasl_callback_t ) ); if( session_callbacks == NULL ) return LDAP_NO_MEMORY; @@ -412,29 +449,49 @@ ldap_int_sasl_open( return ld->ld_errno; } +#if SASL_VERSION_MAJOR >= 2 + rc = sasl_client_new( "ldap", host, NULL, NULL, + session_callbacks, 0, &ctx ); +#else rc = sasl_client_new( "ldap", host, session_callbacks, SASL_SECURITY_LAYER, &ctx ); +#endif + LDAP_FREE( session_callbacks ); if ( rc != SASL_OK ) { ld->ld_errno = sasl_err2ldap( rc ); return ld->ld_errno; } - Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: %s\n", +#ifdef NEW_LOGGING + LDAP_LOG (( "cyrus", LDAP_LEVEL_DETAIL1, + "ldap_int_sasl_open: host=%s\n", host )); +#else + Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: host=%s\n", host, 0, 0 ); +#endif lc->lconn_sasl_ctx = ctx; if( ssf ) { +#if SASL_VERSION_MAJOR >= 2 + (void) sasl_setprop( ctx, SASL_SSF_EXTERNAL, + (void *) &ssf ); +#else sasl_external_properties_t extprops; memset(&extprops, 0L, sizeof(extprops)); extprops.ssf = ssf; (void) sasl_setprop( ctx, SASL_SSF_EXTERNAL, (void *) &extprops ); - +#endif +#ifdef NEW_LOGGING + LDAP_LOG (( "cyrus", LDAP_LEVEL_DETAIL1, + "ldap_int_sasl_open: ssf=%ld\n", (long) ssf )); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: ssf=%ld\n", (long) ssf, 0, 0 ); +#endif } return LDAP_SUCCESS; @@ -474,8 +531,13 @@ ldap_int_sasl_bind( struct berval ccred; ber_socket_t sd; +#ifdef NEW_LOGGING + LDAP_LOG (( "cyrus", LDAP_LEVEL_ARGS, + "ldap_int_sasl_bind: %s\n", mechs ? mechs : "" )); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n", mechs ? mechs : "", 0, 0 ); +#endif /* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */ if (ld->ld_version < LDAP_VERSION3) { @@ -517,9 +579,11 @@ ldap_int_sasl_bind( do { saslrc = sasl_client_start( ctx, mechs, +#if SASL_VERSION_MAJOR < 2 NULL, +#endif &prompts, - &ccred.bv_val, + (SASL_CONST char **)&ccred.bv_val, &credlen, &mech ); @@ -533,6 +597,14 @@ ldap_int_sasl_bind( } } +#if SASL_VERSION_MAJOR >= 2 + /* XXX the application should free interact results. */ + if ( prompts != NULL && prompts->result != NULL ) { + LDAP_FREE( (void *)prompts->result ); + prompts->result = NULL; + } +#endif + if( saslrc == SASL_INTERACT ) { int res; if( !interact ) break; @@ -559,16 +631,24 @@ ldap_int_sasl_bind( rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred ); if ( ccred.bv_val != NULL ) { +#if SASL_VERSION_MAJOR < 2 LDAP_FREE( ccred.bv_val ); +#endif ccred.bv_val = NULL; } if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) { if( scred && scred->bv_len ) { /* and server provided us with data? */ +#ifdef NEW_LOGGING + LDAP_LOG (( "cyrus", LDAP_LEVEL_DETAIL1, + "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", + rc, saslrc, scred->bv_len )); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", rc, saslrc, scred->bv_len ); +#endif ber_bvfree( scred ); } return ld->ld_errno; @@ -578,9 +658,15 @@ ldap_int_sasl_bind( /* we're done, no need to step */ if( scred && scred->bv_len ) { /* but server provided us with data! */ +#ifdef NEW_LOGGING + LDAP_LOG (( "cyrus", LDAP_LEVEL_DETAIL1, + "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", + rc, saslrc, scred->bv_len )); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", rc, saslrc, scred->bv_len ); +#endif ber_bvfree( scred ); return ld->ld_errno = LDAP_LOCAL_ERROR; } @@ -592,11 +678,24 @@ ldap_int_sasl_bind( (scred == NULL) ? NULL : scred->bv_val, (scred == NULL) ? 0 : scred->bv_len, &prompts, - &ccred.bv_val, + (SASL_CONST char **)&ccred.bv_val, &credlen ); - Debug( LDAP_DEBUG_TRACE, "sasl_client_start: %d\n", +#ifdef NEW_LOGGING + LDAP_LOG (( "cyrus", LDAP_LEVEL_DETAIL1, + "ldap_int_sasl_bind: sasl_client_step: %d\n", saslrc )); +#else + Debug( LDAP_DEBUG_TRACE, "sasl_client_step: %d\n", saslrc, 0, 0 ); +#endif + +#if SASL_VERSION_MAJOR >= 2 + /* XXX the application should free interact results. */ + if ( prompts != NULL && prompts->result != NULL ) { + LDAP_FREE( (void *)prompts->result ); + prompts->result = NULL; + } +#endif if( saslrc == SASL_INTERACT ) { int res; @@ -626,18 +725,22 @@ ldap_int_sasl_bind( } if( flags != LDAP_SASL_QUIET ) { - saslrc = sasl_getprop( ctx, SASL_USERNAME, (void **) &data ); + saslrc = sasl_getprop( ctx, SASL_USERNAME, (SASL_CONST void **) &data ); if( saslrc == SASL_OK && data && *data ) { fprintf( stderr, "SASL username: %s\n", data ); } - saslrc = sasl_getprop( ctx, SASL_REALM, (void **) &data ); +#if SASL_VERSION_MAJOR >= 2 + saslrc = sasl_getprop( ctx, SASL_DEFUSERREALM, (SASL_CONST void **) &data ); +#else + saslrc = sasl_getprop( ctx, SASL_REALM, (SASL_CONST void **) &data ); +#endif if( saslrc == SASL_OK && data && *data ) { fprintf( stderr, "SASL realm: %s\n", data ); } } - saslrc = sasl_getprop( ctx, SASL_SSF, (void **) &ssf ); + saslrc = sasl_getprop( ctx, SASL_SSF, (SASL_CONST void **) &ssf ); if( saslrc == SASL_OK ) { if( flags != LDAP_SASL_QUIET ) { fprintf( stderr, "SASL SSF: %lu\n", @@ -648,7 +751,7 @@ ldap_int_sasl_bind( if( flags != LDAP_SASL_QUIET ) { fprintf( stderr, "SASL installing layers\n" ); } - ldap_pvt_sasl_install( ld->ld_sb, ctx ); + ldap_pvt_sasl_install( ld->ld_conns->lconn_sb, ctx ); } } @@ -658,30 +761,33 @@ ldap_int_sasl_bind( int ldap_int_sasl_external( LDAP *ld, + LDAPConn *conn, const char * authid, ber_len_t ssf ) { int sc; sasl_conn_t *ctx; +#if SASL_VERSION_MAJOR < 2 sasl_external_properties_t extprops; +#endif - if( ld->ld_defconn == NULL ) { - return LDAP_LOCAL_ERROR; - } - - ctx = ld->ld_defconn->lconn_sasl_ctx; + ctx = conn->lconn_sasl_ctx; if ( ctx == NULL ) { return LDAP_LOCAL_ERROR; } - + +#if SASL_VERSION_MAJOR >= 2 + sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, &ssf ); +#else memset( &extprops, '\0', sizeof(extprops) ); extprops.ssf = ssf; extprops.auth_id = (char *) authid; - + sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, (void *) &extprops ); - +#endif + if ( sc != SASL_OK ) { return LDAP_LOCAL_ERROR; } @@ -767,7 +873,10 @@ int ldap_pvt_sasl_secprops( return LDAP_NOT_SUPPORTED; } - if( maxbufsize > SASL_MAX_BUFF_SIZE ) { + if( maxbufsize && (( maxbufsize < SASL_MIN_BUFF_SIZE ) + || (maxbufsize > SASL_MAX_BUFF_SIZE ))) + { + /* bad maxbufsize */ return LDAP_PARAM_ERROR; } @@ -847,7 +956,7 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg ) } sc = sasl_getprop( ctx, SASL_SSF, - (void **) &ssf ); + (SASL_CONST void **) &ssf ); if ( sc != SASL_OK ) { return -1; @@ -893,7 +1002,9 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg ) case LDAP_OPT_X_SASL_SSF_EXTERNAL: { int sc; +#if SASL_VERSION_MAJOR < 2 sasl_external_properties_t extprops; +#endif sasl_conn_t *ctx; if( ld->ld_defconn == NULL ) { @@ -906,12 +1017,16 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg ) return -1; } +#if SASL_VERSION_MAJOR >= 2 + sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, arg); +#else memset(&extprops, 0L, sizeof(extprops)); extprops.ssf = * (ber_len_t *) arg; sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, (void *) &extprops ); +#endif if ( sc != SASL_OK ) { return -1; @@ -997,6 +1112,7 @@ ldap_int_sasl_bind( int ldap_int_sasl_external( LDAP *ld, + LDAPConn *conn, const char * authid, ber_len_t ssf ) { return LDAP_SUCCESS; }