X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fcyrus.c;h=5310903c0ea570f59d59c2395ab7139e8bf6399f;hb=3b9f4a82ee478c943a66696adf9133dc9f503e16;hp=3349fc994217fe0f76a2d9c75f9b06fc851b55d3;hpb=6393523ffa71bffabcafffda064c04b36742cb2c;p=openldap diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index 3349fc9942..5310903c0e 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -1,34 +1,44 @@ /* $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. */ -#define SASL_MAX_BUFF_SIZE 65536 -#define SASL_MIN_BUFF_SIZE 4096 - int ldap_int_sasl_init( void ) { /* XXX not threadsafe */ @@ -64,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 ) { @@ -80,6 +92,7 @@ int ldap_int_sasl_init( void ) struct sb_sasl_data { sasl_conn_t *sasl_context; + unsigned *sasl_maxbuf; Sockbuf_Buf sec_buf_in; Sockbuf_Buf buf_in; Sockbuf_Buf buf_out; @@ -100,9 +113,12 @@ sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg ) ber_pvt_sb_buf_init( &p->buf_in ); ber_pvt_sb_buf_init( &p->buf_out ); if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, SASL_MIN_BUFF_SIZE ) < 0 ) { + LBER_FREE( p ); errno = ENOMEM; return -1; } + sasl_getprop( p->sasl_context, SASL_MAXOUTBUF, + (SASL_CONST void **) &p->sasl_maxbuf ); sbiod->sbiod_pvt = p; @@ -117,6 +133,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 ); @@ -126,15 +150,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, unsigned max, 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]; if ( size > SASL_MAX_BUFF_SIZE ) { /* somebody is trying to mess me up. */ @@ -142,25 +167,29 @@ sb_sasl_pkt_length( const char *buf, int debuglevel ) "sb_sasl_pkt_length: received illegal packet length " "of %lu bytes\n", (unsigned long)size ); size = 16; /* this should lead to an error. */ -} + } else if ( size > max ) { + ber_log_printf( LDAP_DEBUG_ANY, debuglevel, + "sb_sasl_pkt_length: received packet length " + "of %lu exceeds negotiated max of %lu bytes\n", (unsigned long)size, (unsigned long)max ); + } return size + 4; /* include the size !!! */ } /* Drop a processed packet from the input buffer */ static void -sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel ) +sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, unsigned max, int debuglevel ) { ber_slen_t len; 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 ) { sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base, - debuglevel); + max, debuglevel); } else { sec_buf_in->buf_end = 0; @@ -187,7 +216,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 ) { @@ -205,11 +238,12 @@ 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, - sbiod->sbiod_sb->sb_debug ); + *p->sasl_maxbuf, sbiod->sbiod_sb->sb_debug ); /* 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 ) { + if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) && + ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) + { errno = ENOMEM; return -1; } @@ -234,21 +268,22 @@ 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 ); + + /* Drop the packet from the input buffer */ + sb_sasl_drop_packet( &p->sec_buf_in, + *p->sasl_maxbuf, sbiod->sbiod_sb->sb_debug ); + if ( ret != SASL_OK ) { ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug, "sb_sasl_read: failed to decode packet: %s\n", sasl_errstring( ret, NULL, NULL ) ); - sb_sasl_drop_packet( &p->sec_buf_in, - sbiod->sbiod_sb->sb_debug ); errno = EIO; return -1; } - /* Drop the packet from the input buffer */ - sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug ); - p->buf_in.buf_size = p->buf_in.buf_end; bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len ); @@ -275,8 +310,15 @@ 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 + if ( len > *p->sasl_maxbuf - 100 ) + len = *p->sasl_maxbuf - 100; /* For safety margin */ + 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, @@ -318,15 +360,25 @@ Sockbuf_IO ldap_pvt_sockbuf_io_sasl = { int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg ) { +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, ENTRY, "ldap_pvt_sasl_install\n", 0, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_install\n", 0, 0, 0 ); +#endif /* don't install the stuff unless security has been negotiated */ 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; } @@ -340,6 +392,9 @@ sasl_err2ldap( int saslerr ) case SASL_CONTINUE: rc = LDAP_MORE_RESULTS_TO_RETURN; break; + case SASL_INTERACT: + rc = LDAP_LOCAL_ERROR; + break; case SASL_OK: rc = LDAP_SUCCESS; break; @@ -381,55 +436,55 @@ ldap_int_sasl_open( int rc; sasl_conn_t *ctx; - sasl_callback_t *session_callbacks = - ber_memcalloc( 2, sizeof( sasl_callback_t ) ); - - if( session_callbacks == NULL ) return LDAP_NO_MEMORY; - - session_callbacks[0].id = SASL_CB_USER; - session_callbacks[0].proc = NULL; - session_callbacks[0].context = ld; - - session_callbacks[1].id = SASL_CB_LIST_END; - session_callbacks[1].proc = NULL; - session_callbacks[1].context = NULL; - 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, -#ifdef LDAP_SASL_SECURITY_LAYER - SASL_SECURITY_LAYER, +#if SASL_VERSION_MAJOR >= 2 + rc = sasl_client_new( "ldap", host, NULL, NULL, + NULL, 0, &ctx ); #else - 0, + rc = sasl_client_new( "ldap", host, NULL, + SASL_SECURITY_LAYER, &ctx ); #endif - &ctx ); 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 ( TRANSPORT, DETAIL1, "ldap_int_sasl_open: host=%s\n", + host, 0, 0 ); +#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 ( TRANSPORT, DETAIL1, + "ldap_int_sasl_open: ssf=%ld\n", (long) ssf, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: ssf=%ld\n", (long) ssf, 0, 0 ); +#endif } return LDAP_SUCCESS; @@ -438,9 +493,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; } @@ -467,11 +521,16 @@ ldap_int_sasl_bind( sasl_conn_t *ctx; sasl_interact_t *prompts = NULL; unsigned credlen; - struct berval ccred, *scred; + struct berval ccred; ber_socket_t sd; +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, ARGS, "ldap_int_sasl_bind: %s\n", + mechs ? mechs : "", 0, 0 ); +#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) { @@ -483,13 +542,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; } } @@ -497,7 +558,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; } @@ -511,9 +572,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 ); @@ -527,10 +590,19 @@ 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; - rc = (interact)( ld, flags, defaults, prompts ); - if( rc != LDAP_SUCCESS ) { + res = (interact)( ld, flags, defaults, prompts ); + if( res != LDAP_SUCCESS ) { break; } } @@ -540,28 +612,61 @@ 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 ); +#endif return ld->ld_errno; } - scred = NULL; - do { + struct berval *scred; unsigned credlen; + scred = NULL; + rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred ); - if ( rc == LDAP_SUCCESS ) { - break; - } else if ( rc != LDAP_SASL_BIND_IN_PROGRESS ) { - if ( ccred.bv_val != NULL ) { - LDAP_FREE( ccred.bv_val ); + 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 ( TRANSPORT, 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; } - if ( ccred.bv_val != NULL ) { - LDAP_FREE( ccred.bv_val ); - ccred.bv_val = NULL; + if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) { + /* we're done, no need to step */ + if( scred && scred->bv_len ) { + /* but server provided us with data! */ +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, 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; + } + break; } do { @@ -569,16 +674,29 @@ 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 ( TRANSPORT, DETAIL1, + "ldap_int_sasl_bind: sasl_client_step: %d\n", saslrc,0,0 ); +#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; if( !interact ) break; - rc = (interact)( ld, flags, defaults, prompts ); + res = (interact)( ld, flags, defaults, prompts ); if( res != LDAP_SUCCESS ) { break; } @@ -590,46 +708,98 @@ 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 ); +#endif return ld->ld_errno; } } while ( rc == LDAP_SASL_BIND_IN_PROGRESS ); - assert ( rc == LDAP_SUCCESS ); + if ( rc != LDAP_SUCCESS ) { + return rc; + } - /* likely should add a quiet option */ + if ( saslrc != SASL_OK ) { +#if SASL_VERSION_MAJOR >= 2 + ld->ld_error = (char *)sasl_errdetail( ctx ); +#endif + return ld->ld_errno = sasl_err2ldap( saslrc ); + } if( flags != LDAP_SASL_QUIET ) { - saslrc = sasl_getprop( ctx, SASL_USERNAME, (void **) &data ); - if( saslrc == SASL_OK ) { + 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( saslrc == SASL_OK ) { +#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", (unsigned long) *ssf ); } -#ifdef LDAP_SASL_SECURITY_LAYER if( ssf && *ssf ) { 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 ); } -#endif } return rc; } +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 + + 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 ); + if ( sc == SASL_OK ) + sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL, authid ); +#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; + } + + return LDAP_SUCCESS; +} + + int ldap_pvt_sasl_secprops( const char *in, sasl_security_properties_t *secprops ) @@ -638,11 +808,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 ) { @@ -680,8 +850,8 @@ int ldap_pvt_sasl_secprops( } else if( !strncasecmp(props[i], "minssf=", sizeof("minssf")) ) { - if( isdigit( props[i][sizeof("minssf")] ) ) { - got_max_ssf++; + if( isdigit( (unsigned char) props[i][sizeof("minssf")] ) ) { + got_min_ssf++; min_ssf = atoi( &props[i][sizeof("minssf")] ); } else { return LDAP_NOT_SUPPORTED; @@ -690,7 +860,7 @@ int ldap_pvt_sasl_secprops( } else if( !strncasecmp(props[i], "maxssf=", sizeof("maxssf")) ) { - if( isdigit( props[i][sizeof("maxssf")] ) ) { + if( isdigit( (unsigned char) props[i][sizeof("maxssf")] ) ) { got_max_ssf++; max_ssf = atoi( &props[i][sizeof("maxssf")] ); } else { @@ -700,13 +870,20 @@ int ldap_pvt_sasl_secprops( } else if( !strncasecmp(props[i], "maxbufsize=", sizeof("maxbufsize")) ) { - if( isdigit( props[i][sizeof("maxbufsize")] ) ) { + if( isdigit( (unsigned char) props[i][sizeof("maxbufsize")] ) ) { got_maxbufsize++; maxbufsize = atoi( &props[i][sizeof("maxbufsize")] ); } else { 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; } @@ -783,7 +960,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; @@ -829,7 +1006,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 ) { @@ -842,12 +1021,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; @@ -924,6 +1107,18 @@ ldap_int_sasl_bind( const char *dn, const char *mechs, LDAPControl **sctrls, - LDAPControl **cctrls ) + LDAPControl **cctrls, + unsigned flags, + 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 */