3 * Copyright 1999-2002 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
11 #include <ac/socket.h>
12 #include <ac/stdlib.h>
13 #include <ac/string.h>
20 #ifdef HAVE_CYRUS_SASL
23 ldap_pvt_thread_mutex_t ldap_int_sasl_mutex;
28 #if SASL_VERSION_MAJOR >= 2
29 #define SASL_CONST const
35 * Various Cyrus SASL related stuff.
38 int ldap_int_sasl_init( void )
40 /* XXX not threadsafe */
41 static int sasl_initialized = 0;
43 static sasl_callback_t client_callbacks[] = {
44 #ifdef SASL_CB_GETREALM
45 { SASL_CB_GETREALM, NULL, NULL },
47 { SASL_CB_USER, NULL, NULL },
48 { SASL_CB_AUTHNAME, NULL, NULL },
49 { SASL_CB_PASS, NULL, NULL },
50 { SASL_CB_ECHOPROMPT, NULL, NULL },
51 { SASL_CB_NOECHOPROMPT, NULL, NULL },
52 { SASL_CB_LIST_END, NULL, NULL }
55 if ( sasl_initialized ) {
65 #endif /* CSRIMALLOC */
69 ldap_pvt_sasl_mutex_new,
70 ldap_pvt_sasl_mutex_lock,
71 ldap_pvt_sasl_mutex_unlock,
72 ldap_pvt_sasl_mutex_dispose );
74 ldap_pvt_thread_mutex_init( &ldap_int_sasl_mutex );
77 if ( sasl_client_init( client_callbacks ) == SASL_OK ) {
86 * SASL encryption support for LBER Sockbufs
90 sasl_conn_t *sasl_context;
91 Sockbuf_Buf sec_buf_in;
97 sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg )
99 struct sb_sasl_data *p;
101 assert( sbiod != NULL );
103 p = LBER_MALLOC( sizeof( *p ) );
106 p->sasl_context = (sasl_conn_t *)arg;
107 ber_pvt_sb_buf_init( &p->sec_buf_in );
108 ber_pvt_sb_buf_init( &p->buf_in );
109 ber_pvt_sb_buf_init( &p->buf_out );
110 if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, SASL_MIN_BUFF_SIZE ) < 0 ) {
115 sbiod->sbiod_pvt = p;
121 sb_sasl_remove( Sockbuf_IO_Desc *sbiod )
123 struct sb_sasl_data *p;
125 assert( sbiod != NULL );
127 p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
128 #if SASL_VERSION_MAJOR >= 2
130 * SASLv2 encode/decode buffers are managed by
131 * libsasl2. Ensure they are not freed by liblber.
133 p->buf_in.buf_base = NULL;
134 p->buf_out.buf_base = NULL;
136 ber_pvt_sb_buf_destroy( &p->sec_buf_in );
137 ber_pvt_sb_buf_destroy( &p->buf_in );
138 ber_pvt_sb_buf_destroy( &p->buf_out );
140 sbiod->sbiod_pvt = NULL;
145 sb_sasl_pkt_length( const unsigned char *buf, int debuglevel )
149 assert( buf != NULL );
156 /* we really should check against actual buffer size set
159 if ( size > SASL_MAX_BUFF_SIZE ) {
160 /* somebody is trying to mess me up. */
161 ber_log_printf( LDAP_DEBUG_ANY, debuglevel,
162 "sb_sasl_pkt_length: received illegal packet length "
163 "of %lu bytes\n", (unsigned long)size );
164 size = 16; /* this should lead to an error. */
167 return size + 4; /* include the size !!! */
170 /* Drop a processed packet from the input buffer */
172 sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel )
176 len = sec_buf_in->buf_ptr - sec_buf_in->buf_end;
178 AC_MEMCPY( sec_buf_in->buf_base, sec_buf_in->buf_base +
179 sec_buf_in->buf_end, len );
182 sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base,
186 sec_buf_in->buf_end = 0;
188 sec_buf_in->buf_ptr = len;
192 sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
194 struct sb_sasl_data *p;
195 ber_slen_t ret, bufptr;
197 assert( sbiod != NULL );
198 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
200 p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
202 /* Are there anything left in the buffer? */
203 ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len );
210 #if SASL_VERSION_MAJOR >= 2
211 ber_pvt_sb_buf_init( &p->buf_in );
213 ber_pvt_sb_buf_destroy( &p->buf_in );
216 /* Read the length of the packet */
217 while ( p->sec_buf_in.buf_ptr < 4 ) {
218 ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base,
219 4 - p->sec_buf_in.buf_ptr );
221 if ( ( ret < 0 ) && ( errno == EINTR ) )
227 p->sec_buf_in.buf_ptr += ret;
230 /* The new packet always starts at p->sec_buf_in.buf_base */
231 ret = sb_sasl_pkt_length( p->sec_buf_in.buf_base,
232 sbiod->sbiod_sb->sb_debug );
234 /* Grow the packet buffer if neccessary */
235 if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) &&
236 ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 )
241 p->sec_buf_in.buf_end = ret;
243 /* Did we read the whole encrypted packet? */
244 while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) {
245 /* No, we have got only a part of it */
246 ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr;
248 ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
249 p->sec_buf_in.buf_ptr, ret );
251 if ( ( ret < 0 ) && ( errno == EINTR ) )
257 p->sec_buf_in.buf_ptr += ret;
260 /* Decode the packet */
261 ret = sasl_decode( p->sasl_context, p->sec_buf_in.buf_base,
262 p->sec_buf_in.buf_end,
263 (SASL_CONST char **)&p->buf_in.buf_base,
264 (unsigned *)&p->buf_in.buf_end );
265 if ( ret != SASL_OK ) {
266 ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
267 "sb_sasl_read: failed to decode packet: %s\n",
268 sasl_errstring( ret, NULL, NULL ) );
269 sb_sasl_drop_packet( &p->sec_buf_in,
270 sbiod->sbiod_sb->sb_debug );
275 /* Drop the packet from the input buffer */
276 sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug );
278 p->buf_in.buf_size = p->buf_in.buf_end;
280 bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len );
286 sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
288 struct sb_sasl_data *p;
291 assert( sbiod != NULL );
292 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
294 p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
296 /* Are there anything left in the buffer? */
297 if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
298 ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
303 /* now encode the next packet. */
304 #if SASL_VERSION_MAJOR >= 2
305 ber_pvt_sb_buf_init( &p->buf_out );
307 ber_pvt_sb_buf_destroy( &p->buf_out );
309 ret = sasl_encode( p->sasl_context, buf, len,
310 (SASL_CONST char **)&p->buf_out.buf_base,
311 (unsigned *)&p->buf_out.buf_size );
312 if ( ret != SASL_OK ) {
313 ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
314 "sb_sasl_write: failed to encode packet: %s\n",
315 sasl_errstring( ret, NULL, NULL ) );
318 p->buf_out.buf_end = p->buf_out.buf_size;
320 ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
327 sb_sasl_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
329 struct sb_sasl_data *p;
331 p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
333 if ( opt == LBER_SB_OPT_DATA_READY ) {
334 if ( p->buf_in.buf_ptr != p->buf_in.buf_end )
338 return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
341 Sockbuf_IO ldap_pvt_sockbuf_io_sasl = {
342 sb_sasl_setup, /* sbi_setup */
343 sb_sasl_remove, /* sbi_remove */
344 sb_sasl_ctrl, /* sbi_ctrl */
345 sb_sasl_read, /* sbi_read */
346 sb_sasl_write, /* sbi_write */
350 int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
352 Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_install\n",
355 /* don't install the stuff unless security has been negotiated */
357 if ( !ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO,
358 &ldap_pvt_sockbuf_io_sasl ) )
361 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
362 LBER_SBIOD_LEVEL_APPLICATION, (void *)"sasl_" );
364 ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_sasl,
365 LBER_SBIOD_LEVEL_APPLICATION, ctx_arg );
372 sasl_err2ldap( int saslerr )
378 rc = LDAP_MORE_RESULTS_TO_RETURN;
381 rc = LDAP_LOCAL_ERROR;
387 rc = LDAP_LOCAL_ERROR;
393 rc = LDAP_AUTH_UNKNOWN;
396 rc = LDAP_AUTH_UNKNOWN;
399 rc = LDAP_PARAM_ERROR;
403 rc = LDAP_AUTH_UNKNOWN;
406 rc = LDAP_LOCAL_ERROR;
410 assert( rc == LDAP_SUCCESS || LDAP_API_ERROR( rc ) );
424 sasl_callback_t *session_callbacks =
425 LDAP_CALLOC( 2, sizeof( sasl_callback_t ) );
427 if( session_callbacks == NULL ) return LDAP_NO_MEMORY;
429 session_callbacks[0].id = SASL_CB_USER;
430 session_callbacks[0].proc = NULL;
431 session_callbacks[0].context = ld;
433 session_callbacks[1].id = SASL_CB_LIST_END;
434 session_callbacks[1].proc = NULL;
435 session_callbacks[1].context = NULL;
437 assert( lc->lconn_sasl_ctx == NULL );
439 if ( host == NULL ) {
440 ld->ld_errno = LDAP_LOCAL_ERROR;
444 #if SASL_VERSION_MAJOR >= 2
445 rc = sasl_client_new( "ldap", host, NULL, NULL,
446 session_callbacks, 0, &ctx );
448 rc = sasl_client_new( "ldap", host, session_callbacks,
449 SASL_SECURITY_LAYER, &ctx );
451 LDAP_FREE( session_callbacks );
453 if ( rc != SASL_OK ) {
454 ld->ld_errno = sasl_err2ldap( rc );
458 Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: host=%s\n",
461 lc->lconn_sasl_ctx = ctx;
464 #if SASL_VERSION_MAJOR >= 2
465 (void) sasl_setprop( ctx, SASL_SSF_EXTERNAL,
468 sasl_external_properties_t extprops;
469 memset(&extprops, 0L, sizeof(extprops));
472 (void) sasl_setprop( ctx, SASL_SSF_EXTERNAL,
473 (void *) &extprops );
475 Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: ssf=%ld\n",
482 int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
484 sasl_conn_t *ctx = lc->lconn_sasl_ctx;
487 sasl_dispose( &ctx );
488 lc->lconn_sasl_ctx = NULL;
499 LDAPControl **sctrls,
500 LDAPControl **cctrls,
502 LDAP_SASL_INTERACT_PROC *interact,
506 const char *mech = NULL;
507 const char *pmech = NULL;
509 sasl_ssf_t *ssf = NULL;
511 sasl_interact_t *prompts = NULL;
516 Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n",
517 mechs ? mechs : "<null>", 0, 0 );
519 /* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */
520 if (ld->ld_version < LDAP_VERSION3) {
521 ld->ld_errno = LDAP_NOT_SUPPORTED;
525 ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
527 if ( sd == AC_SOCKET_INVALID ) {
528 /* not connected yet */
531 rc = ldap_open_defconn( ld );
532 if( rc < 0 ) return ld->ld_errno;
534 ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
536 if( sd == AC_SOCKET_INVALID ) {
537 ld->ld_errno = LDAP_LOCAL_ERROR;
542 ctx = ld->ld_defconn->lconn_sasl_ctx;
545 ld->ld_errno = LDAP_LOCAL_ERROR;
549 /* (re)set security properties */
550 sasl_setprop( ctx, SASL_SEC_PROPS,
551 &ld->ld_options.ldo_sasl_secprops );
557 saslrc = sasl_client_start( ctx,
559 #if SASL_VERSION_MAJOR < 2
563 (SASL_CONST char **)&ccred.bv_val,
567 if( pmech == NULL && mech != NULL ) {
570 if( flags != LDAP_SASL_QUIET ) {
572 "SASL/%s authentication started\n",
577 #if SASL_VERSION_MAJOR >= 2
578 /* XXX the application should free interact results. */
579 if ( prompts != NULL && prompts->result != NULL ) {
580 LDAP_FREE( (void *)prompts->result );
581 prompts->result = NULL;
585 if( saslrc == SASL_INTERACT ) {
587 if( !interact ) break;
588 res = (interact)( ld, flags, defaults, prompts );
589 if( res != LDAP_SUCCESS ) {
593 } while ( saslrc == SASL_INTERACT );
595 ccred.bv_len = credlen;
597 if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
598 ld->ld_errno = sasl_err2ldap( saslrc );
603 struct berval *scred;
608 rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
610 if ( ccred.bv_val != NULL ) {
611 #if SASL_VERSION_MAJOR < 2
612 LDAP_FREE( ccred.bv_val );
617 if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
618 if( scred && scred->bv_len ) {
619 /* and server provided us with data? */
620 Debug( LDAP_DEBUG_TRACE,
621 "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
622 rc, saslrc, scred->bv_len );
628 if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
629 /* we're done, no need to step */
630 if( scred && scred->bv_len ) {
631 /* but server provided us with data! */
632 Debug( LDAP_DEBUG_TRACE,
633 "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
634 rc, saslrc, scred->bv_len );
636 return ld->ld_errno = LDAP_LOCAL_ERROR;
642 saslrc = sasl_client_step( ctx,
643 (scred == NULL) ? NULL : scred->bv_val,
644 (scred == NULL) ? 0 : scred->bv_len,
646 (SASL_CONST char **)&ccred.bv_val,
649 Debug( LDAP_DEBUG_TRACE, "sasl_client_start: %d\n",
652 #if SASL_VERSION_MAJOR >= 2
653 /* XXX the application should free interact results. */
654 if ( prompts != NULL && prompts->result != NULL ) {
655 LDAP_FREE( (void *)prompts->result );
656 prompts->result = NULL;
660 if( saslrc == SASL_INTERACT ) {
662 if( !interact ) break;
663 res = (interact)( ld, flags, defaults, prompts );
664 if( res != LDAP_SUCCESS ) {
668 } while ( saslrc == SASL_INTERACT );
670 ccred.bv_len = credlen;
673 if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
674 ld->ld_errno = sasl_err2ldap( saslrc );
677 } while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
679 if ( rc != LDAP_SUCCESS ) {
683 if ( saslrc != SASL_OK ) {
684 return ld->ld_errno = sasl_err2ldap( saslrc );
687 if( flags != LDAP_SASL_QUIET ) {
688 saslrc = sasl_getprop( ctx, SASL_USERNAME, (SASL_CONST void **) &data );
689 if( saslrc == SASL_OK && data && *data ) {
690 fprintf( stderr, "SASL username: %s\n", data );
693 #if SASL_VERSION_MAJOR >= 2
694 saslrc = sasl_getprop( ctx, SASL_DEFUSERREALM, (SASL_CONST void **) &data );
696 saslrc = sasl_getprop( ctx, SASL_REALM, (SASL_CONST void **) &data );
698 if( saslrc == SASL_OK && data && *data ) {
699 fprintf( stderr, "SASL realm: %s\n", data );
703 saslrc = sasl_getprop( ctx, SASL_SSF, (SASL_CONST void **) &ssf );
704 if( saslrc == SASL_OK ) {
705 if( flags != LDAP_SASL_QUIET ) {
706 fprintf( stderr, "SASL SSF: %lu\n",
707 (unsigned long) *ssf );
711 if( flags != LDAP_SASL_QUIET ) {
712 fprintf( stderr, "SASL installing layers\n" );
714 ldap_pvt_sasl_install( ld->ld_conns->lconn_sb, ctx );
722 ldap_int_sasl_external(
730 #if SASL_VERSION_MAJOR < 2
731 sasl_external_properties_t extprops;
734 ctx = conn->lconn_sasl_ctx;
737 return LDAP_LOCAL_ERROR;
740 #if SASL_VERSION_MAJOR >= 2
741 sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, &ssf );
743 memset( &extprops, '\0', sizeof(extprops) );
745 extprops.auth_id = (char *) authid;
747 sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL,
748 (void *) &extprops );
751 if ( sc != SASL_OK ) {
752 return LDAP_LOCAL_ERROR;
759 int ldap_pvt_sasl_secprops(
761 sasl_security_properties_t *secprops )
764 char **props = ldap_str2charray( in, "," );
767 sasl_ssf_t max_ssf = 0;
769 sasl_ssf_t min_ssf = 0;
771 unsigned maxbufsize = 0;
772 int got_maxbufsize = 0;
774 if( props == NULL || secprops == NULL ) {
775 return LDAP_PARAM_ERROR;
778 for( i=0; props[i]; i++ ) {
779 if( !strcasecmp(props[i], "none") ) {
782 } else if( !strcasecmp(props[i], "noplain") ) {
784 sflags |= SASL_SEC_NOPLAINTEXT;
786 } else if( !strcasecmp(props[i], "noactive") ) {
788 sflags |= SASL_SEC_NOACTIVE;
790 } else if( !strcasecmp(props[i], "nodict") ) {
792 sflags |= SASL_SEC_NODICTIONARY;
794 } else if( !strcasecmp(props[i], "forwardsec") ) {
796 sflags |= SASL_SEC_FORWARD_SECRECY;
798 } else if( !strcasecmp(props[i], "noanonymous")) {
800 sflags |= SASL_SEC_NOANONYMOUS;
802 } else if( !strcasecmp(props[i], "passcred") ) {
804 sflags |= SASL_SEC_PASS_CREDENTIALS;
806 } else if( !strncasecmp(props[i],
807 "minssf=", sizeof("minssf")) )
809 if( isdigit( props[i][sizeof("minssf")] ) ) {
811 min_ssf = atoi( &props[i][sizeof("minssf")] );
813 return LDAP_NOT_SUPPORTED;
816 } else if( !strncasecmp(props[i],
817 "maxssf=", sizeof("maxssf")) )
819 if( isdigit( props[i][sizeof("maxssf")] ) ) {
821 max_ssf = atoi( &props[i][sizeof("maxssf")] );
823 return LDAP_NOT_SUPPORTED;
826 } else if( !strncasecmp(props[i],
827 "maxbufsize=", sizeof("maxbufsize")) )
829 if( isdigit( props[i][sizeof("maxbufsize")] ) ) {
831 maxbufsize = atoi( &props[i][sizeof("maxbufsize")] );
833 return LDAP_NOT_SUPPORTED;
836 if( maxbufsize && (( maxbufsize < SASL_MIN_BUFF_SIZE )
837 || (maxbufsize > SASL_MAX_BUFF_SIZE )))
840 return LDAP_PARAM_ERROR;
844 return LDAP_NOT_SUPPORTED;
849 secprops->security_flags = sflags;
852 secprops->min_ssf = min_ssf;
855 secprops->max_ssf = max_ssf;
858 secprops->maxbufsize = maxbufsize;
861 ldap_charray_free( props );
866 ldap_int_sasl_config( struct ldapoptions *lo, int option, const char *arg )
871 case LDAP_OPT_X_SASL_SECPROPS:
872 rc = ldap_pvt_sasl_secprops( arg, &lo->ldo_sasl_secprops );
873 if( rc == LDAP_SUCCESS ) return 0;
880 ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
886 case LDAP_OPT_X_SASL_MECH: {
887 *(char **)arg = ld->ld_options.ldo_def_sasl_mech
888 ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_mech ) : NULL;
890 case LDAP_OPT_X_SASL_REALM: {
891 *(char **)arg = ld->ld_options.ldo_def_sasl_realm
892 ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_realm ) : NULL;
894 case LDAP_OPT_X_SASL_AUTHCID: {
895 *(char **)arg = ld->ld_options.ldo_def_sasl_authcid
896 ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authcid ) : NULL;
898 case LDAP_OPT_X_SASL_AUTHZID: {
899 *(char **)arg = ld->ld_options.ldo_def_sasl_authzid
900 ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authzid ) : NULL;
903 case LDAP_OPT_X_SASL_SSF: {
908 if( ld->ld_defconn == NULL ) {
912 ctx = ld->ld_defconn->lconn_sasl_ctx;
918 sc = sasl_getprop( ctx, SASL_SSF,
919 (SASL_CONST void **) &ssf );
921 if ( sc != SASL_OK ) {
925 *(ber_len_t *)arg = *ssf;
928 case LDAP_OPT_X_SASL_SSF_EXTERNAL:
929 /* this option is write only */
932 case LDAP_OPT_X_SASL_SSF_MIN:
933 *(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.min_ssf;
935 case LDAP_OPT_X_SASL_SSF_MAX:
936 *(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.max_ssf;
938 case LDAP_OPT_X_SASL_MAXBUFSIZE:
939 *(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.maxbufsize;
942 case LDAP_OPT_X_SASL_SECPROPS:
943 /* this option is write only */
953 ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
959 case LDAP_OPT_X_SASL_SSF:
960 /* This option is read-only */
963 case LDAP_OPT_X_SASL_SSF_EXTERNAL: {
965 #if SASL_VERSION_MAJOR < 2
966 sasl_external_properties_t extprops;
970 if( ld->ld_defconn == NULL ) {
974 ctx = ld->ld_defconn->lconn_sasl_ctx;
980 #if SASL_VERSION_MAJOR >= 2
981 sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, arg);
983 memset(&extprops, 0L, sizeof(extprops));
985 extprops.ssf = * (ber_len_t *) arg;
987 sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL,
988 (void *) &extprops );
991 if ( sc != SASL_OK ) {
996 case LDAP_OPT_X_SASL_SSF_MIN:
997 ld->ld_options.ldo_sasl_secprops.min_ssf = *(ber_len_t *)arg;
999 case LDAP_OPT_X_SASL_SSF_MAX:
1000 ld->ld_options.ldo_sasl_secprops.max_ssf = *(ber_len_t *)arg;
1002 case LDAP_OPT_X_SASL_MAXBUFSIZE:
1003 ld->ld_options.ldo_sasl_secprops.maxbufsize = *(ber_len_t *)arg;
1006 case LDAP_OPT_X_SASL_SECPROPS: {
1008 sc = ldap_pvt_sasl_secprops( (char *) arg,
1009 &ld->ld_options.ldo_sasl_secprops );
1011 return sc == LDAP_SUCCESS ? 0 : -1;
1020 #ifdef LDAP_R_COMPILE
1021 void *ldap_pvt_sasl_mutex_new(void)
1023 ldap_pvt_thread_mutex_t *mutex;
1025 mutex = (ldap_pvt_thread_mutex_t *) LDAP_MALLOC(
1026 sizeof(ldap_pvt_thread_mutex_t) );
1028 if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
1034 int ldap_pvt_sasl_mutex_lock(void *mutex)
1036 return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex )
1037 ? SASL_FAIL : SASL_OK;
1040 int ldap_pvt_sasl_mutex_unlock(void *mutex)
1042 return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex )
1043 ? SASL_FAIL : SASL_OK;
1046 void ldap_pvt_sasl_mutex_dispose(void *mutex)
1048 (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
1054 int ldap_int_sasl_init( void )
1055 { return LDAP_SUCCESS; }
1057 int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
1058 { return LDAP_SUCCESS; }
1065 LDAPControl **sctrls,
1066 LDAPControl **cctrls,
1068 LDAP_SASL_INTERACT_PROC *interact,
1070 { return LDAP_NOT_SUPPORTED; }
1073 ldap_int_sasl_external(
1076 const char * authid,
1078 { return LDAP_SUCCESS; }
1080 #endif /* HAVE_CYRUS_SASL */