Back to index

openldap  2.4.31
Defines | Functions | Variables
sasl.c File Reference
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/string.h>
#include <lber.h>
#include <ldap_log.h>
#include "slap.h"
#include <lutil.h>

Go to the source code of this file.

Defines

#define SET_NONE   0
#define SET_DN   1
#define SET_U   2

Functions

int slap_sasl_init (void)
int slap_sasl_destroy (void)
static char * slap_sasl_peer2ipport (struct berval *peer)
int slap_sasl_open (Connection *conn, int reopen)
int slap_sasl_external (Connection *conn, slap_ssf_t ssf, struct berval *auth_id)
int slap_sasl_reset (Connection *conn)
char ** slap_sasl_mechs (Connection *conn)
int slap_sasl_close (Connection *conn)
int slap_sasl_bind (Operation *op, SlapReply *rs)
char * slap_sasl_secprops (const char *in)
void slap_sasl_secprops_unparse (struct berval *bv)
int slap_sasl_getdn (Connection *conn, Operation *op, struct berval *id, char *user_realm, struct berval *dn, int flags)

Variables

static struct berval = BER_BVC( "EXTERNAL" )
char * slap_sasl_auxprops

Define Documentation

#define SET_DN   1

Definition at line 1709 of file sasl.c.

#define SET_NONE   0

Definition at line 1708 of file sasl.c.

#define SET_U   2

Definition at line 1710 of file sasl.c.


Function Documentation

int slap_sasl_bind ( Operation op,
SlapReply rs 
)

Definition at line 1460 of file sasl.c.

{
#ifdef HAVE_CYRUS_SASL
       sasl_conn_t *ctx = op->o_conn->c_sasl_authctx;
       struct berval response;
       unsigned reslen = 0;
       int sc;

       Debug(LDAP_DEBUG_ARGS,
              "==> sasl_bind: dn=\"%s\" mech=%s datalen=%ld\n",
              op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "",
              op->o_conn->c_sasl_bind_in_progress ? "<continuing>" : 
              op->o_conn->c_sasl_bind_mech.bv_val,
              op->orb_cred.bv_len );

       if( ctx == NULL ) {
              send_ldap_error( op, rs, LDAP_UNAVAILABLE,
                     "SASL unavailable on this session" );
              return rs->sr_err;
       }

#define       START( ctx, mech, cred, clen, resp, rlen, err ) \
       sasl_server_start( ctx, mech, cred, clen, resp, rlen )
#define       STEP( ctx, cred, clen, resp, rlen, err ) \
       sasl_server_step( ctx, cred, clen, resp, rlen )

       if ( !op->o_conn->c_sasl_bind_in_progress ) {
              /* If we already authenticated once, must use a new context */
              if ( op->o_conn->c_sasl_done ) {
                     sasl_ssf_t ssf = 0;
                     const char *authid = NULL;
                     sasl_getprop( ctx, SASL_SSF_EXTERNAL, (void *)&ssf );
                     sasl_getprop( ctx, SASL_AUTH_EXTERNAL, (void *)&authid );
                     if ( authid ) authid = ch_strdup( authid );
                     if ( ctx != op->o_conn->c_sasl_sockctx ) {
                            sasl_dispose( &ctx );
                     }
                     op->o_conn->c_sasl_authctx = NULL;
                            
                     slap_sasl_open( op->o_conn, 1 );
                     ctx = op->o_conn->c_sasl_authctx;
                     if ( authid ) {
                            sasl_setprop( ctx, SASL_SSF_EXTERNAL, &ssf );
                            sasl_setprop( ctx, SASL_AUTH_EXTERNAL, authid );
                            ch_free( (char *)authid );
                     }
              }
              sc = START( ctx,
                     op->o_conn->c_sasl_bind_mech.bv_val,
                     op->orb_cred.bv_val, op->orb_cred.bv_len,
                     (SASL_CONST char **)&response.bv_val, &reslen, &rs->sr_text );

       } else {
              sc = STEP( ctx,
                     op->orb_cred.bv_val, op->orb_cred.bv_len,
                     (SASL_CONST char **)&response.bv_val, &reslen, &rs->sr_text );
       }

       response.bv_len = reslen;

       if ( sc == SASL_OK ) {
              sasl_ssf_t *ssf = NULL;

              ber_dupbv_x( &op->orb_edn, &op->o_conn->c_sasl_dn, op->o_tmpmemctx );
              BER_BVZERO( &op->o_conn->c_sasl_dn );
              op->o_conn->c_sasl_done = 1;

              rs->sr_err = LDAP_SUCCESS;

              (void) sasl_getprop( ctx, SASL_SSF, (void *)&ssf );
              op->orb_ssf = ssf ? *ssf : 0;

              ctx = NULL;
              if( op->orb_ssf ) {
                     ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
                     op->o_conn->c_sasl_layers++;

                     /* If there's an old layer, set sockctx to NULL to
                      * tell connection_read() to wait for us to finish.
                      * Otherwise there is a race condition: we have to
                      * send the Bind response using the old security
                      * context and then remove it before reading any
                      * new messages.
                      */
                     if ( op->o_conn->c_sasl_sockctx ) {
                            ctx = op->o_conn->c_sasl_sockctx;
                            op->o_conn->c_sasl_sockctx = NULL;
                     } else {
                            op->o_conn->c_sasl_sockctx = op->o_conn->c_sasl_authctx;
                     }
                     ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
              }

              /* Must send response using old security layer */
              rs->sr_sasldata = (response.bv_len ? &response : NULL);
              send_ldap_sasl( op, rs );
              
              /* Now dispose of the old security layer.
               */
              if ( ctx ) {
                     ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
                     ldap_pvt_sasl_remove( op->o_conn->c_sb );
                     op->o_conn->c_sasl_sockctx = op->o_conn->c_sasl_authctx;
                     ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
                     sasl_dispose( &ctx );
              }
       } else if ( sc == SASL_CONTINUE ) {
              rs->sr_err = LDAP_SASL_BIND_IN_PROGRESS,
              rs->sr_text = sasl_errdetail( ctx );
              rs->sr_sasldata = &response;
              send_ldap_sasl( op, rs );

       } else {
              BER_BVZERO( &op->o_conn->c_sasl_dn );
              rs->sr_text = sasl_errdetail( ctx );
              rs->sr_err = slap_sasl_err2ldap( sc ),
              send_ldap_result( op, rs );
       }

       Debug(LDAP_DEBUG_TRACE, "<== slap_sasl_bind: rc=%d\n", rs->sr_err, 0, 0);

#elif defined(SLAP_BUILTIN_SASL)
       /* built-in SASL implementation */
       SASL_CTX *ctx = op->o_conn->c_sasl_authctx;

       if ( ctx == NULL ) {
              send_ldap_error( op, rs, LDAP_OTHER,
                     "Internal SASL Error" );

       } else if ( bvmatch( &ext_bv, &op->o_conn->c_sasl_bind_mech ) ) {
              /* EXTERNAL */

              if( op->orb_cred.bv_len ) {
                     rs->sr_text = "proxy authorization not supported";
                     rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                     send_ldap_result( op, rs );

              } else {
                     op->orb_edn = ctx->sc_external_id;
                     rs->sr_err = LDAP_SUCCESS;
                     rs->sr_sasldata = NULL;
                     send_ldap_sasl( op, rs );
              }

       } else {
              send_ldap_error( op, rs, LDAP_AUTH_METHOD_NOT_SUPPORTED,
                     "requested SASL mechanism not supported" );
       }
#else
       send_ldap_error( op, rs, LDAP_AUTH_METHOD_NOT_SUPPORTED,
              "SASL not supported" );
#endif

       return rs->sr_err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1423 of file sasl.c.

{
#ifdef HAVE_CYRUS_SASL
       sasl_conn_t *ctx = conn->c_sasl_authctx;

       if( ctx != NULL ) {
              sasl_dispose( &ctx );
       }
       if ( conn->c_sasl_sockctx &&
              conn->c_sasl_authctx != conn->c_sasl_sockctx )
       {
              ctx = conn->c_sasl_sockctx;
              sasl_dispose( &ctx );
       }

       conn->c_sasl_authctx = NULL;
       conn->c_sasl_sockctx = NULL;
       conn->c_sasl_done = 0;

       free( conn->c_sasl_extra );
       conn->c_sasl_extra = NULL;

#elif defined(SLAP_BUILTIN_SASL)
       SASL_CTX *ctx = conn->c_sasl_authctx;
       if( ctx ) {
              if( ctx->sc_external_id.bv_val ) {
                     free( ctx->sc_external_id.bv_val );
                     BER_BVZERO( &ctx->sc_external_id );
              }
              free( ctx );
              conn->c_sasl_authctx = NULL;
       }
#endif

       return LDAP_SUCCESS;
}

Here is the caller graph for this function:

Definition at line 1187 of file sasl.c.

{
#ifdef HAVE_CYRUS_SASL
       sasl_done();
#endif
       free( sasl_host );
       sasl_host = NULL;

       return 0;
}

Here is the caller graph for this function:

int slap_sasl_external ( Connection conn,
slap_ssf_t  ssf,
struct berval auth_id 
)

Definition at line 1337 of file sasl.c.

{
#ifdef HAVE_CYRUS_SASL
       int sc;
       sasl_conn_t *ctx = conn->c_sasl_authctx;
       sasl_ssf_t sasl_ssf = ssf;

       if ( ctx == NULL ) {
              return LDAP_UNAVAILABLE;
       }

       sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, &sasl_ssf );

       if ( sc != SASL_OK ) {
              return LDAP_OTHER;
       }

       sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL,
              auth_id ? auth_id->bv_val : NULL );

       if ( sc != SASL_OK ) {
              return LDAP_OTHER;
       }
#elif defined(SLAP_BUILTIN_SASL)
       /* built-in SASL implementation */
       SASL_CTX *ctx = conn->c_sasl_authctx;
       if ( ctx == NULL ) return LDAP_UNAVAILABLE;

       ctx->sc_external_ssf = ssf;
       if( auth_id ) {
              ctx->sc_external_id = *auth_id;
              BER_BVZERO( auth_id );
       } else {
              BER_BVZERO( &ctx->sc_external_id );
       }
#endif

       return LDAP_SUCCESS;
}

Here is the caller graph for this function:

int slap_sasl_getdn ( Connection conn,
Operation op,
struct berval id,
char *  user_realm,
struct berval dn,
int  flags 
)

Definition at line 1712 of file sasl.c.

{
       int rc, is_dn = SET_NONE, do_norm = 1;
       struct berval dn2, *mech;

       assert( conn != NULL );
       assert( id != NULL );

       Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: conn %lu id=%s [len=%lu]\n", 
              conn->c_connid,
              BER_BVISNULL( id ) ? "NULL" : ( BER_BVISEMPTY( id ) ? "<empty>" : id->bv_val ),
              BER_BVISNULL( id ) ? 0 : ( BER_BVISEMPTY( id ) ? 0 :
                                         (unsigned long) id->bv_len ) );

       if ( !op ) {
              op = conn->c_sasl_bindop;
       }
       assert( op != NULL );

       BER_BVZERO( dn );

       if ( !BER_BVISNULL( id ) ) {
              /* Blatantly anonymous ID */
              static struct berval bv_anonymous = BER_BVC( "anonymous" );

              if ( ber_bvstrcasecmp( id, &bv_anonymous ) == 0 ) {
                     return( LDAP_SUCCESS );
              }

       } else {
              /* FIXME: if empty, should we stop? */
              BER_BVSTR( id, "" );
       }

       if ( !BER_BVISEMPTY( &conn->c_sasl_bind_mech ) ) {
              mech = &conn->c_sasl_bind_mech;
       } else {
              mech = &conn->c_authmech;
       }

       /* An authcID needs to be converted to authzID form. Set the
        * values directly into *dn; they will be normalized later. (and
        * normalizing always makes a new copy.) An ID from a TLS certificate
        * is already normalized, so copy it and skip normalization.
        */
       if( flags & SLAP_GETDN_AUTHCID ) {
              if( bvmatch( mech, &ext_bv )) {
                     /* EXTERNAL DNs are already normalized */
                     assert( !BER_BVISNULL( id ) );

                     do_norm = 0;
                     is_dn = SET_DN;
                     ber_dupbv_x( dn, id, op->o_tmpmemctx );

              } else {
                     /* convert to u:<username> form */
                     is_dn = SET_U;
                     *dn = *id;
              }
       }

       if( is_dn == SET_NONE ) {
              if( !strncasecmp( id->bv_val, "u:", STRLENOF( "u:" ) ) ) {
                     is_dn = SET_U;
                     dn->bv_val = id->bv_val + STRLENOF( "u:" );
                     dn->bv_len = id->bv_len - STRLENOF( "u:" );

              } else if ( !strncasecmp( id->bv_val, "dn:", STRLENOF( "dn:" ) ) ) {
                     is_dn = SET_DN;
                     dn->bv_val = id->bv_val + STRLENOF( "dn:" );
                     dn->bv_len = id->bv_len - STRLENOF( "dn:" );
              }
       }

       /* No other possibilities from here */
       if( is_dn == SET_NONE ) {
              BER_BVZERO( dn );
              return( LDAP_INAPPROPRIATE_AUTH );
       }

       /* Username strings */
       if( is_dn == SET_U ) {
              /* ITS#3419: values may need escape */
              LDAPRDN              DN[ 5 ];
              LDAPAVA       *RDNs[ 4 ][ 2 ];
              LDAPAVA       AVAs[ 4 ];
              int           irdn;

              irdn = 0;
              DN[ irdn ] = RDNs[ irdn ];
              RDNs[ irdn ][ 0 ] = &AVAs[ irdn ];
              AVAs[ irdn ].la_attr = slap_schema.si_ad_uid->ad_cname;
              AVAs[ irdn ].la_value = *dn;
              AVAs[ irdn ].la_flags = LDAP_AVA_NULL;
              AVAs[ irdn ].la_private = NULL;
              RDNs[ irdn ][ 1 ] = NULL;

              if ( user_realm && *user_realm ) {
                     irdn++;
                     DN[ irdn ] = RDNs[ irdn ];
                     RDNs[ irdn ][ 0 ] = &AVAs[ irdn ];
                     AVAs[ irdn ].la_attr = slap_schema.si_ad_cn->ad_cname;
                     ber_str2bv( user_realm, 0, 0, &AVAs[ irdn ].la_value );
                     AVAs[ irdn ].la_flags = LDAP_AVA_NULL;
                     AVAs[ irdn ].la_private = NULL;
                     RDNs[ irdn ][ 1 ] = NULL;
              }

              if ( !BER_BVISNULL( mech ) ) {
                     irdn++;
                     DN[ irdn ] = RDNs[ irdn ];
                     RDNs[ irdn ][ 0 ] = &AVAs[ irdn ];
                     AVAs[ irdn ].la_attr = slap_schema.si_ad_cn->ad_cname;
                     AVAs[ irdn ].la_value = *mech;
                     AVAs[ irdn ].la_flags = LDAP_AVA_NULL;
                     AVAs[ irdn ].la_private = NULL;
                     RDNs[ irdn ][ 1 ] = NULL;
              }

              irdn++;
              DN[ irdn ] = RDNs[ irdn ];
              RDNs[ irdn ][ 0 ] = &AVAs[ irdn ];
              AVAs[ irdn ].la_attr = slap_schema.si_ad_cn->ad_cname;
              BER_BVSTR( &AVAs[ irdn ].la_value, "auth" );
              AVAs[ irdn ].la_flags = LDAP_AVA_NULL;
              AVAs[ irdn ].la_private = NULL;
              RDNs[ irdn ][ 1 ] = NULL;

              irdn++;
              DN[ irdn ] = NULL;

              rc = ldap_dn2bv_x( DN, dn, LDAP_DN_FORMAT_LDAPV3,
                            op->o_tmpmemctx );
              if ( rc != LDAP_SUCCESS ) {
                     BER_BVZERO( dn );
                     return rc;
              }

              Debug( LDAP_DEBUG_TRACE,
                     "slap_sasl_getdn: u:id converted to %s\n",
                     dn->bv_val, 0, 0 );

       } else {
              
              /* Dup the DN in any case, so we don't risk 
               * leaks or dangling pointers later,
               * and the DN value is '\0' terminated */
              ber_dupbv_x( &dn2, dn, op->o_tmpmemctx );
              dn->bv_val = dn2.bv_val;
       }

       /* All strings are in DN form now. Normalize if needed. */
       if ( do_norm ) {
              rc = dnNormalize( 0, NULL, NULL, dn, &dn2, op->o_tmpmemctx );

              /* User DNs were constructed above and must be freed now */
              slap_sl_free( dn->bv_val, op->o_tmpmemctx );

              if ( rc != LDAP_SUCCESS ) {
                     BER_BVZERO( dn );
                     return rc;
              }
              *dn = dn2;
       }

       /* Run thru regexp */
       slap_sasl2dn( op, dn, &dn2, flags );
       if( !BER_BVISNULL( &dn2 ) ) {
              slap_sl_free( dn->bv_val, op->o_tmpmemctx );
              *dn = dn2;
              Debug( LDAP_DEBUG_TRACE,
                     "slap_sasl_getdn: dn:id converted to %s\n",
                     dn->bv_val, 0, 0 );
       }

       return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1107 of file sasl.c.

{
#ifdef HAVE_CYRUS_SASL
       int rc;
       static sasl_callback_t server_callbacks[] = {
              { SASL_CB_LOG, &slap_sasl_log, NULL },
              { SASL_CB_GETOPT, &slap_sasl_getopt, NULL },
              { SASL_CB_LIST_END, NULL, NULL }
       };
#endif

#ifdef ENABLE_REWRITE
       rewrite_mapper_register( &slapd_mapper );
#endif

#ifdef HAVE_CYRUS_SASL
#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)

       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 );
              Debug( LDAP_DEBUG_ANY, "slap_sasl_init: SASL library version mismatch:"
                     " expected %s, got %s\n",
                     SASL_VERSION_STRING, version, 0 );
              return -1;
       }
#endif

       sasl_set_mutex(
              ldap_pvt_sasl_mutex_new,
              ldap_pvt_sasl_mutex_lock,
              ldap_pvt_sasl_mutex_unlock,
              ldap_pvt_sasl_mutex_dispose );

       generic_filter.f_desc = slap_schema.si_ad_objectClass;

       rc = sasl_auxprop_add_plugin( "slapd", slap_auxprop_init );
       if( rc != SASL_OK ) {
              Debug( LDAP_DEBUG_ANY, "slap_sasl_init: auxprop add plugin failed\n",
                     0, 0, 0 );
              return -1;
       }

       /* should provide callbacks for logging */
       /* server name should be configurable */
       rc = sasl_server_init( server_callbacks, "slapd" );

       if( rc != SASL_OK ) {
              Debug( LDAP_DEBUG_ANY, "slap_sasl_init: server init failed\n",
                     0, 0, 0 );

              return -1;
       }

#ifdef SLAPD_SPASSWD
       lutil_passwd_add( &sasl_pwscheme, chk_sasl, NULL );
#endif

       Debug( LDAP_DEBUG_TRACE, "slap_sasl_init: initialized!\n",
              0, 0, 0 );

       /* default security properties */
       memset( &sasl_secprops, '\0', sizeof(sasl_secprops) );
       sasl_secprops.max_ssf = INT_MAX;
       sasl_secprops.maxbufsize = 65536;
       sasl_secprops.security_flags = SASL_SEC_NOPLAINTEXT|SASL_SEC_NOANONYMOUS;
#endif

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char** slap_sasl_mechs ( Connection conn)

Definition at line 1385 of file sasl.c.

{
       char **mechs = NULL;

#ifdef HAVE_CYRUS_SASL
       sasl_conn_t *ctx = conn->c_sasl_authctx;

       if( ctx == NULL ) ctx = conn->c_sasl_sockctx;

       if( ctx != NULL ) {
              int sc;
              SASL_CONST char *mechstr;

              sc = sasl_listmech( ctx,
                     NULL, NULL, ",", NULL,
                     &mechstr, NULL, NULL );

              if( sc != SASL_OK ) {
                     Debug( LDAP_DEBUG_ANY, "slap_sasl_listmech failed: %d\n",
                            sc, 0, 0 );

                     return NULL;
              }

              mechs = ldap_str2charray( mechstr, "," );
       }
#elif defined(SLAP_BUILTIN_SASL)
       /* builtin SASL implementation */
       SASL_CTX *ctx = conn->c_sasl_authctx;
       if ( ctx != NULL && ctx->sc_external_id.bv_val ) {
              /* should check ssf */
              mechs = ldap_str2charray( "EXTERNAL", "," );
       }
#endif

       return mechs;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int slap_sasl_open ( Connection conn,
int  reopen 
)

Definition at line 1232 of file sasl.c.

{
       int sc = LDAP_SUCCESS;
#ifdef HAVE_CYRUS_SASL
       int cb;

       sasl_conn_t *ctx = NULL;
       sasl_callback_t *session_callbacks;
       char *ipremoteport = NULL, *iplocalport = NULL;

       assert( conn->c_sasl_authctx == NULL );

       if ( !reopen ) {
              assert( conn->c_sasl_extra == NULL );

              session_callbacks =
                     SLAP_CALLOC( 5, sizeof(sasl_callback_t));
              if( session_callbacks == NULL ) {
                     Debug( LDAP_DEBUG_ANY, 
                            "slap_sasl_open: SLAP_MALLOC failed", 0, 0, 0 );
                     return -1;
              }
              conn->c_sasl_extra = session_callbacks;

              session_callbacks[cb=0].id = SASL_CB_LOG;
              session_callbacks[cb].proc = &slap_sasl_log;
              session_callbacks[cb++].context = conn;

              session_callbacks[cb].id = SASL_CB_PROXY_POLICY;
              session_callbacks[cb].proc = &slap_sasl_authorize;
              session_callbacks[cb++].context = conn;

              session_callbacks[cb].id = SASL_CB_CANON_USER;
              session_callbacks[cb].proc = &slap_sasl_canonicalize;
              session_callbacks[cb++].context = conn;

              session_callbacks[cb].id = SASL_CB_LIST_END;
              session_callbacks[cb].proc = NULL;
              session_callbacks[cb++].context = NULL;
       } else {
              session_callbacks = conn->c_sasl_extra;
       }

       conn->c_sasl_layers = 0;

       /* create new SASL context */
       if ( conn->c_sock_name.bv_len != 0 &&
              strncmp( conn->c_sock_name.bv_val, "IP=", STRLENOF( "IP=" ) ) == 0 )
       {
              iplocalport = slap_sasl_peer2ipport( &conn->c_sock_name );
       }

       if ( conn->c_peer_name.bv_len != 0 &&
              strncmp( conn->c_peer_name.bv_val, "IP=", STRLENOF( "IP=" ) ) == 0 )
       {
              ipremoteport = slap_sasl_peer2ipport( &conn->c_peer_name );
       }

       sc = sasl_server_new( "ldap", sasl_host, global_realm,
              iplocalport, ipremoteport, session_callbacks, SASL_SUCCESS_DATA, &ctx );
       if ( iplocalport != NULL ) {
              ch_free( iplocalport );
       }
       if ( ipremoteport != NULL ) {
              ch_free( ipremoteport );
       }

       if( sc != SASL_OK ) {
              Debug( LDAP_DEBUG_ANY, "sasl_server_new failed: %d\n",
                     sc, 0, 0 );

              return -1;
       }

       conn->c_sasl_authctx = ctx;

       if( sc == SASL_OK ) {
              sc = sasl_setprop( ctx,
                     SASL_SEC_PROPS, &sasl_secprops );

              if( sc != SASL_OK ) {
                     Debug( LDAP_DEBUG_ANY, "sasl_setprop failed: %d\n",
                            sc, 0, 0 );

                     slap_sasl_close( conn );
                     return -1;
              }
       }

       sc = slap_sasl_err2ldap( sc );

#elif defined(SLAP_BUILTIN_SASL)
       /* built-in SASL implementation */
       SASL_CTX *ctx = (SASL_CTX *) SLAP_MALLOC(sizeof(SASL_CTX));
       if( ctx == NULL ) return -1;

       ctx->sc_external_ssf = 0;
       BER_BVZERO( &ctx->sc_external_id );

       conn->c_sasl_authctx = ctx;
#endif

       return sc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* slap_sasl_peer2ipport ( struct berval peer) [static]

Definition at line 1199 of file sasl.c.

{
       int           isv6 = 0;
       char          *ipport, *p,
                     *addr = &peer->bv_val[ STRLENOF( "IP=" ) ];
       ber_len_t     plen = peer->bv_len - STRLENOF( "IP=" );

       /* IPv6? */
       if ( addr[0] == '[' ) {
              isv6 = 1;
              plen--;
       }
       ipport = ch_strdup( &addr[isv6] );

       /* Convert IPv6/IPv4 addresses to address;port syntax. */
       p = strrchr( ipport, ':' );
       if ( p != NULL ) {
              *p = ';';
              if ( isv6 ) {
                     assert( p[-1] == ']' );
                     AC_MEMCPY( &p[-1], p, plen - ( p - ipport ) + 1 );
              }

       } else if ( isv6 ) {
              /* trim ']' */
              plen--;
              assert( addr[plen] == ']' );
              addr[plen] = '\0';
       }

       return ipport;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1380 of file sasl.c.

{
       return LDAP_SUCCESS;
}

Here is the caller graph for this function:

char* slap_sasl_secprops ( const char *  in)

Definition at line 1616 of file sasl.c.

{
#ifdef HAVE_CYRUS_SASL
       int rc = ldap_pvt_sasl_secprops( in, &sasl_secprops );

       return rc == LDAP_SUCCESS ? NULL : "Invalid security properties";
#else
       return "SASL not supported";
#endif
}

Here is the caller graph for this function:

Definition at line 1627 of file sasl.c.

{
#ifdef HAVE_CYRUS_SASL
       ldap_pvt_sasl_secprops_unparse( &sasl_secprops, bv );
#endif
}

Here is the caller graph for this function:


Variable Documentation

struct berval = BER_BVC( "EXTERNAL" ) [static]

Definition at line 64 of file sasl.c.

Definition at line 66 of file sasl.c.