X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fcyrus.c;h=339d21dc8720d94d1e82fc8942bd7627cbd900a0;hb=4d29df5bd1fabcdc50975651c746365686b62b53;hp=abed0261a44a88bd18126d9af02f72d6aa56add8;hpb=5f25c10980d24df1ea2d4eb9e3696529737522c6;p=openldap diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index abed0261a4..339d21dc87 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -1,19 +1,29 @@ /* $OpenLDAP$ */ -/* - * Copyright 1999-2000 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2003 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ #include "portable.h" -#include #include #include +#include #include #include #include #include +#include #include "ldap-int.h" @@ -23,7 +33,17 @@ ldap_pvt_thread_mutex_t ldap_int_sasl_mutex; #endif +#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. @@ -46,11 +66,41 @@ int ldap_int_sasl_init( void ) { SASL_CB_LIST_END, NULL, NULL } }; +#ifdef HAVE_SASL_VERSION + /* 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 library version mismatch:" + " expected " SASL_VERSION_STRING "," + " got %s\n", version, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "ldap_int_sasl_init: SASL library version mismatch:" + " expected " SASL_VERSION_STRING "," + " got %s\n", version, 0, 0 ); +#endif + return -1; + } + } +#endif if ( sasl_initialized ) { return 0; } -#ifndef CSRIMALLOC +/* SASL 2 takes care of its own memory completely internally */ +#if SASL_VERSION_MAJOR < 2 && !defined(CSRIMALLOC) sasl_set_alloc( ber_memalloc, ber_memcalloc, @@ -73,6 +123,10 @@ int ldap_int_sasl_init( void ) return 0; } +#if SASL_VERSION_MAJOR < 2 + /* A no-op to make sure we link with Cyrus 1.5 */ + sasl_client_auth( NULL, NULL, NULL, 0, NULL, NULL ); +#endif return -1; } @@ -82,6 +136,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; @@ -102,10 +157,13 @@ 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; return 0; @@ -119,6 +177,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 ); @@ -139,9 +205,6 @@ sb_sasl_pkt_length( const unsigned char *buf, int debuglevel ) | 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, @@ -161,12 +224,12 @@ 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 ) { - sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base, - debuglevel); + sec_buf_in->buf_end = sb_sasl_pkt_length( + (unsigned char *) sec_buf_in->buf_base, debuglevel); } else { sec_buf_in->buf_end = 0; @@ -193,7 +256,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 ) { @@ -204,17 +271,17 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) continue; #endif if ( ret <= 0 ) - return ret; + return bufptr ? bufptr : ret; p->sec_buf_in.buf_ptr += ret; } /* 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, 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; @@ -234,28 +301,28 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) continue; #endif if ( ret <= 0 ) - return ret; + return bufptr ? bufptr : ret; p->sec_buf_in.buf_ptr += ret; } /* 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, 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 ); @@ -277,13 +344,28 @@ sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) /* Are there anything left in the buffer? */ if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) { ret = ber_pvt_sb_do_write( sbiod, &p->buf_out ); - if ( ret <= 0 ) + if ( ret < 0 ) return ret; + /* Still have something left?? */ + if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) { + errno = EAGAIN; + return 0; + } } /* now encode the next packet. */ +#if SASL_VERSION_MAJOR >= 2 + ber_pvt_sb_buf_init( &p->buf_out ); + /* sasl v2 makes sure this number is correct */ + if ( len > *p->sasl_maxbuf ) + len = *p->sasl_maxbuf; +#else ber_pvt_sb_buf_destroy( &p->buf_out ); - ret = sasl_encode( p->sasl_context, buf, len, &p->buf_out.buf_base, + if ( len > *p->sasl_maxbuf - 100 ) + len = *p->sasl_maxbuf - 100; /* For safety margin */ +#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, @@ -325,8 +407,12 @@ 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 */ @@ -344,6 +430,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 ) { @@ -391,67 +487,62 @@ int ldap_int_sasl_open( LDAP *ld, LDAPConn *lc, - const char * host, - ber_len_t ssf ) + const char * host ) { 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 ); + assert( lc->lconn_sasl_authctx == NULL ); if ( host == NULL ) { ld->ld_errno = LDAP_LOCAL_ERROR; return ld->ld_errno; } - rc = sasl_client_new( "ldap", host, session_callbacks, + if ( ldap_int_sasl_init() ) { + ld->ld_errno = LDAP_LOCAL_ERROR; + return ld->ld_errno; + } + +#if SASL_VERSION_MAJOR >= 2 + rc = sasl_client_new( "ldap", host, NULL, NULL, + NULL, 0, &ctx ); +#else + rc = sasl_client_new( "ldap", host, NULL, SASL_SECURITY_LAYER, &ctx ); +#endif 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 ) { - sasl_external_properties_t extprops; - memset(&extprops, 0L, sizeof(extprops)); - extprops.ssf = ssf; - - (void) sasl_setprop( ctx, SASL_SSF_EXTERNAL, - (void *) &extprops ); - - Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: ssf=%ld\n", - (long) ssf, 0, 0 ); - } + 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; @@ -473,14 +564,20 @@ 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; ber_socket_t sd; + void *ssl; +#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) { @@ -505,11 +602,47 @@ ldap_int_sasl_bind( } } - ctx = ld->ld_defconn->lconn_sasl_ctx; + oldctx = ld->ld_defconn->lconn_sasl_authctx; - if( ctx == NULL ) { - ld->ld_errno = LDAP_LOCAL_ERROR; - return ld->ld_errno; + /* 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; + } + + { char *saslhost = ldap_host_connected_to( ld->ld_sb, "localhost" ); + rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost ); + LDAP_FREE( saslhost ); + } + + if ( rc != LDAP_SUCCESS ) return rc; + + ctx = ld->ld_defconn->lconn_sasl_authctx; + + /* Check for TLS */ + ssl = ldap_pvt_tls_sb_ctx( ld->ld_sb ); + if ( ssl ) { + struct berval authid = { 0, NULL }; + ber_len_t fac; + + fac = ldap_pvt_tls_get_strength( ssl ); + /* failure is OK, we just can't use SASL EXTERNAL */ + (void) ldap_pvt_tls_get_my_dn( ssl, &authid, NULL, 0 ); + + (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac ); + LDAP_FREE( authid.bv_val ); + } + + /* Check for local */ + if ( ldap_pvt_url_scheme2proto( ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC ) { + char authid[sizeof("uidNumber=4294967295+gidNumber=4294967295," + "cn=peercred,cn=external,cn=auth")]; + sprintf( authid, "uidNumber=%d+gidNumber=%d," + "cn=peercred,cn=external,cn=auth", + (int) geteuid(), (int) getegid() ); + (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid, LDAP_PVT_SASL_LOCAL_SSF ); } /* (re)set security properties */ @@ -522,9 +655,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 ); @@ -542,17 +677,19 @@ ldap_int_sasl_bind( int res; if( !interact ) break; res = (interact)( ld, flags, defaults, prompts ); - if( res != LDAP_SUCCESS ) { - break; - } + + if( res != LDAP_SUCCESS ) break; } } while ( saslrc == SASL_INTERACT ); ccred.bv_len = credlen; if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) { - ld->ld_errno = sasl_err2ldap( saslrc ); - return ld->ld_errno; + rc = ld->ld_errno = sasl_err2ldap( saslrc ); +#if SASL_VERSION_MAJOR >= 2 + ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) ); +#endif + goto done; } do { @@ -564,30 +701,46 @@ 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 ( 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; + rc = ld->ld_errno; + goto done; } 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; + rc = ld->ld_errno = LDAP_LOCAL_ERROR; + goto done; } break; } @@ -597,19 +750,22 @@ 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( saslrc == SASL_INTERACT ) { int res; if( !interact ) break; res = (interact)( ld, flags, defaults, prompts ); - if( res != LDAP_SUCCESS ) { - break; - } + if( res != LDAP_SUCCESS ) break; } } while ( saslrc == SASL_INTERACT ); @@ -618,31 +774,39 @@ ldap_int_sasl_bind( if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) { ld->ld_errno = sasl_err2ldap( saslrc ); - return ld->ld_errno; +#if SASL_VERSION_MAJOR >= 2 + ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) ); +#endif + rc = ld->ld_errno; + goto done; } } while ( rc == LDAP_SASL_BIND_IN_PROGRESS ); - if ( rc != LDAP_SUCCESS ) { - return rc; - } + if ( rc != LDAP_SUCCESS ) goto done; if ( saslrc != SASL_OK ) { - return ld->ld_errno = sasl_err2ldap( saslrc ); +#if SASL_VERSION_MAJOR >= 2 + ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) ); +#endif + rc = ld->ld_errno = sasl_err2ldap( saslrc ); + goto done; } 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_REALM, (SASL_CONST void **) &data ); if( saslrc == SASL_OK && data && *data ) { fprintf( stderr, "SASL realm: %s\n", data ); } +#endif } - 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", @@ -653,40 +817,53 @@ 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; } 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_authctx; 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; } @@ -745,7 +922,7 @@ int ldap_pvt_sasl_secprops( } else if( !strncasecmp(props[i], "minssf=", sizeof("minssf")) ) { - if( isdigit( props[i][sizeof("minssf")] ) ) { + if( isdigit( (unsigned char) props[i][sizeof("minssf")] ) ) { got_min_ssf++; min_ssf = atoi( &props[i][sizeof("minssf")] ); } else { @@ -755,7 +932,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 { @@ -765,7 +942,7 @@ 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 { @@ -848,14 +1025,14 @@ 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; } sc = sasl_getprop( ctx, SASL_SSF, - (void **) &ssf ); + (SASL_CONST void **) &ssf ); if ( sc != SASL_OK ) { return -1; @@ -901,25 +1078,31 @@ 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 ) { return -1; } - ctx = ld->ld_defconn->lconn_sasl_ctx; + ctx = ld->ld_defconn->lconn_sasl_authctx; if ( ctx == NULL ) { 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; @@ -951,6 +1134,7 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg ) } #ifdef LDAP_R_COMPILE +#define LDAP_DEBUG_R_SASL void *ldap_pvt_sasl_mutex_new(void) { ldap_pvt_thread_mutex_t *mutex; @@ -961,23 +1145,47 @@ void *ldap_pvt_sasl_mutex_new(void) if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) { return mutex; } +#ifndef LDAP_DEBUG_R_SASL + assert( 0 ); +#endif /* !LDAP_DEBUG_R_SASL */ return NULL; } int ldap_pvt_sasl_mutex_lock(void *mutex) { +#ifdef LDAP_DEBUG_R_SASL + if ( mutex == NULL ) { + return SASL_OK; + } +#else /* !LDAP_DEBUG_R_SASL */ + assert( mutex ); +#endif /* !LDAP_DEBUG_R_SASL */ return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex ) ? SASL_FAIL : SASL_OK; } int ldap_pvt_sasl_mutex_unlock(void *mutex) { +#ifdef LDAP_DEBUG_R_SASL + if ( mutex == NULL ) { + return SASL_OK; + } +#else /* !LDAP_DEBUG_R_SASL */ + assert( mutex ); +#endif /* !LDAP_DEBUG_R_SASL */ return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex ) ? SASL_FAIL : SASL_OK; } void ldap_pvt_sasl_mutex_dispose(void *mutex) { +#ifdef LDAP_DEBUG_R_SASL + if ( mutex == NULL ) { + return; + } +#else /* !LDAP_DEBUG_R_SASL */ + assert( mutex ); +#endif /* !LDAP_DEBUG_R_SASL */ (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex ); LDAP_FREE( mutex ); } @@ -1005,6 +1213,7 @@ ldap_int_sasl_bind( int ldap_int_sasl_external( LDAP *ld, + LDAPConn *conn, const char * authid, ber_len_t ssf ) { return LDAP_SUCCESS; }