X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fcyrus.c;h=d262410e33dd55af97eefb49fba857fe8f58b3a1;hb=2b0819c4a9209784f762ec154ce4721038522a8a;hp=0320f7bbc8ed308afd6e1448f39a76e41837e525;hpb=a50f391bb37b059733404b7ec380a883162b23fb;p=openldap diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index 0320f7bbc8..d262410e33 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -13,22 +13,22 @@ #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 #include /* * Various Cyrus SASL related stuff. */ -#define SASL_MAX_BUFF_SIZE 65536 -#define SASL_MIN_BUFF_SIZE 4096 - int ldap_int_sasl_init( void ) { /* XXX not threadsafe */ @@ -64,6 +64,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 ) { @@ -126,23 +128,27 @@ 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. + */ if ( size > SASL_MAX_BUFF_SIZE ) { /* somebody is trying to mess me up. */ ber_log_printf( LDAP_DEBUG_ANY, debuglevel, "sb_sasl_pkt_length: received illegal packet length " "of %lu bytes\n", (unsigned long)size ); size = 16; /* this should lead to an error. */ -} + } return size + 4; /* include the size !!! */ } @@ -209,7 +215,8 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) /* Grow the packet buffer if neccessary */ if ( ( p->sec_buf_in.buf_size < ret ) && - ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) { + ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) + { errno = ENOMEM; return -1; } @@ -325,8 +332,14 @@ int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg ) if ( !ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, &ldap_pvt_sockbuf_io_sasl ) ) + { +#ifdef LDAP_DEBUG + ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, + LBER_SBIOD_LEVEL_APPLICATION, (void *)"sasl_" ); +#endif ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_sasl, LBER_SBIOD_LEVEL_APPLICATION, ctx_arg ); + } return LDAP_SUCCESS; } @@ -400,19 +413,20 @@ ldap_int_sasl_open( assert( lc->lconn_sasl_ctx == NULL ); if ( host == NULL ) { - ld->ld_errno = LDAP_UNAVAILABLE; + ld->ld_errno = LDAP_LOCAL_ERROR; return ld->ld_errno; } rc = sasl_client_new( "ldap", host, session_callbacks, SASL_SECURITY_LAYER, &ctx ); + ber_memfree( 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", + Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: host=%s\n", host, 0, 0 ); lc->lconn_sasl_ctx = ctx; @@ -435,9 +449,8 @@ ldap_int_sasl_open( int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc ) { sasl_conn_t *ctx = lc->lconn_sasl_ctx; - assert( ctx != NULL ); - if( ctx ) { + if( ctx != NULL ) { sasl_dispose( &ctx ); lc->lconn_sasl_ctx = NULL; } @@ -480,13 +493,15 @@ ldap_int_sasl_bind( if ( sd == AC_SOCKET_INVALID ) { /* not connected yet */ - int rc = ldap_open_defconn( ld ); - + int rc; + + rc = ldap_open_defconn( ld ); if( rc < 0 ) return ld->ld_errno; + ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd ); if( sd == AC_SOCKET_INVALID ) { - ld->ld_errno = LDAP_UNAVAILABLE; + ld->ld_errno = LDAP_LOCAL_ERROR; return ld->ld_errno; } } @@ -494,7 +509,7 @@ ldap_int_sasl_bind( ctx = ld->ld_defconn->lconn_sasl_ctx; if( ctx == NULL ) { - ld->ld_errno = LDAP_UNAVAILABLE; + ld->ld_errno = LDAP_LOCAL_ERROR; return ld->ld_errno; } @@ -555,12 +570,19 @@ ldap_int_sasl_bind( } if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) { + if( scred && scred->bv_len ) { + /* and server provided us with data? */ + Debug( LDAP_DEBUG_TRACE, + "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", + rc, saslrc, scred->bv_len ); + ber_bvfree( scred ); + } return ld->ld_errno; } if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) { /* we're done, no need to step */ - if( scred ) { + if( scred && scred->bv_len ) { /* but server provided us with data! */ Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", @@ -609,8 +631,6 @@ ldap_int_sasl_bind( return ld->ld_errno = sasl_err2ldap( saslrc ); } - /* likely should add a quiet option */ - if( flags != LDAP_SASL_QUIET ) { saslrc = sasl_getprop( ctx, SASL_USERNAME, (void **) &data ); if( saslrc == SASL_OK && data && *data ) { @@ -634,13 +654,45 @@ 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 ); } } return rc; } +int +ldap_int_sasl_external( + LDAP *ld, + LDAPConn *conn, + const char * authid, + ber_len_t ssf ) +{ + int sc; + sasl_conn_t *ctx; + sasl_external_properties_t extprops; + + ctx = conn->lconn_sasl_ctx; + + if ( ctx == NULL ) { + return LDAP_LOCAL_ERROR; + } + + memset( &extprops, '\0', sizeof(extprops) ); + extprops.ssf = ssf; + extprops.auth_id = (char *) authid; + + sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, + (void *) &extprops ); + + if ( sc != SASL_OK ) { + return LDAP_LOCAL_ERROR; + } + + return LDAP_SUCCESS; +} + + int ldap_pvt_sasl_secprops( const char *in, sasl_security_properties_t *secprops ) @@ -649,11 +701,11 @@ int ldap_pvt_sasl_secprops( char **props = ldap_str2charray( in, "," ); unsigned sflags = 0; int got_sflags = 0; - sasl_ssf_t max_ssf; + sasl_ssf_t max_ssf = 0; int got_max_ssf = 0; - sasl_ssf_t min_ssf; + sasl_ssf_t min_ssf = 0; int got_min_ssf = 0; - unsigned maxbufsize; + unsigned maxbufsize = 0; int got_maxbufsize = 0; if( props == NULL || secprops == NULL ) { @@ -692,7 +744,7 @@ int ldap_pvt_sasl_secprops( "minssf=", sizeof("minssf")) ) { if( isdigit( props[i][sizeof("minssf")] ) ) { - got_max_ssf++; + got_min_ssf++; min_ssf = atoi( &props[i][sizeof("minssf")] ); } else { return LDAP_NOT_SUPPORTED; @@ -718,6 +770,13 @@ int ldap_pvt_sasl_secprops( return LDAP_NOT_SUPPORTED; } + if( maxbufsize && (( maxbufsize < SASL_MIN_BUFF_SIZE ) + || (maxbufsize > SASL_MAX_BUFF_SIZE ))) + { + /* bad maxbufsize */ + return LDAP_PARAM_ERROR; + } + } else { return LDAP_NOT_SUPPORTED; } @@ -940,4 +999,13 @@ ldap_int_sasl_bind( LDAP_SASL_INTERACT_PROC *interact, void * defaults ) { return LDAP_NOT_SUPPORTED; } + +int +ldap_int_sasl_external( + LDAP *ld, + LDAPConn *conn, + const char * authid, + ber_len_t ssf ) +{ return LDAP_SUCCESS; } + #endif /* HAVE_CYRUS_SASL */