-#ifdef HAVE_CYRUS_SASL
-/*
-* Various Cyrus SASL related stuff.
-*/
-
-static int sasl_setup( Sockbuf *sb, void *arg );
-static int sasl_remove( Sockbuf *sb );
-static ber_slen_t sasl_read( Sockbuf *sb, void *buf, ber_len_t len );
-static ber_slen_t sasl_write( Sockbuf *sb, void *buf, ber_len_t len );
-static int sasl_close( Sockbuf *sb );
-
-static Sockbuf_IO sasl_io=
-{
-sasl_setup,
-sasl_remove,
-sasl_read,
-sasl_write,
-sasl_close
-};
-
-#define HAS_SASL( sb ) ((sb)->sb_io==&sasl_io)
-
-static char *
-array2str( char **a )
-{
- char *s, **v, *p;
- int len = 0;
-
- for ( v = a; *v != NULL; v++ ) {
- len += strlen( *v ) + 1; /* for a space */
- }
-
- if ( len == 0 ) {
- return NULL;
- }
-
- s = LDAP_MALLOC ( len ); /* last space holds \0 */
-
- if ( s == NULL ) {
- return NULL;
- }
-
- p = s;
- for ( v = a; *v != NULL; v++ ) {
- int len;
-
- if ( v != a ) {
- strncpy( p, " ", 1 );
- ++p;
- }
- len = strlen( *v );
- strncpy( p, *v, len );
- p += len;
- }
-
- *p = '\0';
-
- return s;
-}
-
-int ldap_pvt_sasl_init( void )
-{
- /* XXX not threadsafe */
- static int sasl_initialized = 0;
-
- if ( sasl_initialized ) {
- return -1;
- }
-#ifndef CSRIMALLOC
- sasl_set_alloc( ber_memalloc, ber_memcalloc, ber_memrealloc, ber_memfree );
-#endif /* CSRIMALLOC */
-
- if ( sasl_client_init( NULL ) == SASL_OK ) {
- sasl_initialized = 1;
- return 0;
- }
-
- return -1;
-}
-
-int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
-{
- /* don't install the stuff unless security has been negotiated */
-
- if ( !HAS_SASL( sb ) ) {
- ber_pvt_sb_clear_io( sb );
- ber_pvt_sb_set_io( sb, &sasl_io, ctx_arg );
- }
-
- return 0;
-}
-
-static int sasl_setup( Sockbuf *sb, void *arg )
-{
- sb->sb_iodata = arg;
- return 0;
-}
-
-static int sasl_remove( Sockbuf *sb )
-{
- return 0;
-}
-
-static ber_slen_t sasl_read( Sockbuf *sb, void *buf, ber_len_t buflen )
-{
- char *recv_tok;
- unsigned recv_tok_len;
- sasl_conn_t *conn = (sasl_conn_t *)sb->sb_iodata;
-
- if ((ber_pvt_sb_io_tcp.sbi_read)( sb, buf, buflen ) != buflen ) {
- return -1;
- }
-
- if ( sasl_decode( conn, buf, buflen, &recv_tok, &recv_tok_len ) != SASL_OK ) {
- return -1;
- }
-
- if ( recv_tok_len > buflen ) {
- LDAP_FREE( recv_tok );
- return -1;
- }
-
- memcpy( buf, recv_tok, recv_tok_len );
-
- LDAP_FREE( recv_tok );
-
- return recv_tok_len;
-}
-
-static ber_slen_t sasl_write( Sockbuf *sb, void *buf, ber_len_t len )
-{
- char *wrapped_tok;
- unsigned wrapped_tok_len;
- sasl_conn_t *conn = (sasl_conn_t *)sb->sb_iodata;
-
- if ( sasl_encode( conn, (const char *)buf, len,
- &wrapped_tok, &wrapped_tok_len ) != SASL_OK ) {
- return -1;
- }
-
- if ((ber_pvt_sb_io_tcp.sbi_write)( sb, wrapped_tok, wrapped_tok_len ) != wrapped_tok_len ) {
- LDAP_FREE( wrapped_tok );
- return -1;
- }
-
- LDAP_FREE( wrapped_tok );
-
- return len;
-}
-
-static int sasl_close( Sockbuf *sb )
-{
- (ber_pvt_sb_io_tcp.sbi_close)( sb );
-}
-