mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-21 07:09:34 -05:00
Add ldap_sasl_interactive_bind()
This commit is contained in:
parent
0b660dc9f6
commit
fca72f333b
4 changed files with 230 additions and 191 deletions
|
|
@ -1186,6 +1186,26 @@ ldap_sasl_bind LDAP_P((
|
||||||
typedef int (LDAP_SASL_INTERACT_PROC) LDAP_P((
|
typedef int (LDAP_SASL_INTERACT_PROC) LDAP_P((
|
||||||
LDAP *ld, unsigned flags, void* defaults, void *interact ));
|
LDAP *ld, unsigned flags, void* defaults, void *interact ));
|
||||||
|
|
||||||
|
LDAP_F( int )
|
||||||
|
ldap_sasl_interactive_bind LDAP_P((
|
||||||
|
LDAP *ld,
|
||||||
|
LDAP_CONST char *dn, /* usually NULL */
|
||||||
|
LDAP_CONST char *saslMechanism,
|
||||||
|
LDAPControl **serverControls,
|
||||||
|
LDAPControl **clientControls,
|
||||||
|
|
||||||
|
/* should be client controls */
|
||||||
|
unsigned flags,
|
||||||
|
LDAP_SASL_INTERACT_PROC *proc,
|
||||||
|
void *defaults,
|
||||||
|
|
||||||
|
/* as obtained from ldap_result() */
|
||||||
|
LDAPMessage *result,
|
||||||
|
|
||||||
|
/* returned during bind processing */
|
||||||
|
const char **rmech,
|
||||||
|
int *msgid ));
|
||||||
|
|
||||||
LDAP_F( int )
|
LDAP_F( int )
|
||||||
ldap_sasl_interactive_bind_s LDAP_P((
|
ldap_sasl_interactive_bind_s LDAP_P((
|
||||||
LDAP *ld,
|
LDAP *ld,
|
||||||
|
|
|
||||||
|
|
@ -386,19 +386,18 @@ ldap_int_sasl_bind(
|
||||||
LDAPControl **cctrls,
|
LDAPControl **cctrls,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
LDAP_SASL_INTERACT_PROC *interact,
|
LDAP_SASL_INTERACT_PROC *interact,
|
||||||
void * defaults )
|
void *defaults,
|
||||||
|
LDAPMessage *result,
|
||||||
|
const char **rmech,
|
||||||
|
int *msgid )
|
||||||
{
|
{
|
||||||
char *data;
|
const char *mech;
|
||||||
const char *mech = NULL;
|
sasl_ssf_t *ssf;
|
||||||
const char *pmech = NULL;
|
sasl_conn_t *ctx;
|
||||||
int saslrc, rc;
|
|
||||||
sasl_ssf_t *ssf = NULL;
|
|
||||||
sasl_conn_t *ctx, *oldctx = NULL;
|
|
||||||
sasl_interact_t *prompts = NULL;
|
sasl_interact_t *prompts = NULL;
|
||||||
|
struct berval ccred;
|
||||||
|
int saslrc, rc;
|
||||||
unsigned credlen;
|
unsigned credlen;
|
||||||
struct berval ccred;
|
|
||||||
ber_socket_t sd;
|
|
||||||
void *ssl;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n",
|
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n",
|
||||||
mechs ? mechs : "<null>", 0, 0 );
|
mechs ? mechs : "<null>", 0, 0 );
|
||||||
|
|
@ -409,203 +408,161 @@ ldap_int_sasl_bind(
|
||||||
return ld->ld_errno;
|
return ld->ld_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = 0;
|
/* Starting a Bind */
|
||||||
LDAP_MUTEX_LOCK( &ld->ld_req_mutex );
|
if ( !result ) {
|
||||||
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
|
const char *pmech = NULL;
|
||||||
|
sasl_conn_t *oldctx;
|
||||||
|
ber_socket_t sd;
|
||||||
|
void *ssl;
|
||||||
|
|
||||||
if ( sd == AC_SOCKET_INVALID ) {
|
rc = 0;
|
||||||
/* not connected yet */
|
LDAP_MUTEX_LOCK( &ld->ld_req_mutex );
|
||||||
|
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
|
||||||
|
|
||||||
rc = ldap_open_defconn( ld );
|
if ( sd == AC_SOCKET_INVALID ) {
|
||||||
|
/* not connected yet */
|
||||||
|
|
||||||
if ( rc == 0 ) {
|
rc = ldap_open_defconn( ld );
|
||||||
ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb,
|
|
||||||
LBER_SB_OPT_GET_FD, &sd );
|
|
||||||
|
|
||||||
if( sd == AC_SOCKET_INVALID ) {
|
if ( rc == 0 ) {
|
||||||
ld->ld_errno = LDAP_LOCAL_ERROR;
|
ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb,
|
||||||
rc = ld->ld_errno;
|
LBER_SB_OPT_GET_FD, &sd );
|
||||||
|
|
||||||
|
if( sd == AC_SOCKET_INVALID ) {
|
||||||
|
ld->ld_errno = LDAP_LOCAL_ERROR;
|
||||||
|
rc = ld->ld_errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
|
||||||
LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
|
if( rc != 0 ) return ld->ld_errno;
|
||||||
if( rc != 0 ) return ld->ld_errno;
|
|
||||||
|
|
||||||
oldctx = ld->ld_defconn->lconn_sasl_authctx;
|
oldctx = ld->ld_defconn->lconn_sasl_authctx;
|
||||||
|
|
||||||
/* If we already have an authentication context, clear it out */
|
/* If we already have an authentication context, clear it out */
|
||||||
if( oldctx ) {
|
if( oldctx ) {
|
||||||
if ( oldctx != ld->ld_defconn->lconn_sasl_sockctx ) {
|
if ( oldctx != ld->ld_defconn->lconn_sasl_sockctx ) {
|
||||||
sasl_dispose( &oldctx );
|
sasl_dispose( &oldctx );
|
||||||
|
}
|
||||||
|
ld->ld_defconn->lconn_sasl_authctx = NULL;
|
||||||
}
|
}
|
||||||
ld->ld_defconn->lconn_sasl_authctx = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
char *saslhost;
|
char *saslhost;
|
||||||
int nocanon = (int)LDAP_BOOL_GET( &ld->ld_options,
|
int nocanon = (int)LDAP_BOOL_GET( &ld->ld_options,
|
||||||
LDAP_BOOL_SASL_NOCANON );
|
LDAP_BOOL_SASL_NOCANON );
|
||||||
|
|
||||||
/* If we don't need to canonicalize just use the host
|
/* If we don't need to canonicalize just use the host
|
||||||
* from the LDAP URI.
|
* from the LDAP URI.
|
||||||
*/
|
*/
|
||||||
if ( nocanon )
|
if ( nocanon )
|
||||||
saslhost = ld->ld_defconn->lconn_server->lud_host;
|
saslhost = ld->ld_defconn->lconn_server->lud_host;
|
||||||
else
|
else
|
||||||
saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
|
saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
|
||||||
"localhost" );
|
"localhost" );
|
||||||
rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
|
rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
|
||||||
if ( !nocanon )
|
if ( !nocanon )
|
||||||
LDAP_FREE( saslhost );
|
LDAP_FREE( saslhost );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rc != LDAP_SUCCESS ) return rc;
|
if ( rc != LDAP_SUCCESS ) return rc;
|
||||||
|
|
||||||
ctx = ld->ld_defconn->lconn_sasl_authctx;
|
ctx = ld->ld_defconn->lconn_sasl_authctx;
|
||||||
|
|
||||||
#ifdef HAVE_TLS
|
#ifdef HAVE_TLS
|
||||||
/* Check for TLS */
|
/* Check for TLS */
|
||||||
ssl = ldap_pvt_tls_sb_ctx( ld->ld_defconn->lconn_sb );
|
ssl = ldap_pvt_tls_sb_ctx( ld->ld_defconn->lconn_sb );
|
||||||
if ( ssl ) {
|
if ( ssl ) {
|
||||||
struct berval authid = BER_BVNULL;
|
struct berval authid = BER_BVNULL;
|
||||||
ber_len_t fac;
|
ber_len_t fac;
|
||||||
|
|
||||||
fac = ldap_pvt_tls_get_strength( ssl );
|
fac = ldap_pvt_tls_get_strength( ssl );
|
||||||
/* failure is OK, we just can't use SASL EXTERNAL */
|
/* failure is OK, we just can't use SASL EXTERNAL */
|
||||||
(void) ldap_pvt_tls_get_my_dn( ssl, &authid, NULL, 0 );
|
(void) ldap_pvt_tls_get_my_dn( ssl, &authid, NULL, 0 );
|
||||||
|
|
||||||
(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac );
|
(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac );
|
||||||
LDAP_FREE( authid.bv_val );
|
LDAP_FREE( authid.bv_val );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
/* Check for local */
|
/* Check for local */
|
||||||
if ( ldap_pvt_url_scheme2proto(
|
if ( ldap_pvt_url_scheme2proto(
|
||||||
ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC )
|
ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC )
|
||||||
{
|
{
|
||||||
char authid[sizeof("gidNumber=4294967295+uidNumber=4294967295,"
|
char authid[sizeof("gidNumber=4294967295+uidNumber=4294967295,"
|
||||||
"cn=peercred,cn=external,cn=auth")];
|
"cn=peercred,cn=external,cn=auth")];
|
||||||
sprintf( authid, "gidNumber=%u+uidNumber=%u,"
|
sprintf( authid, "gidNumber=%u+uidNumber=%u,"
|
||||||
"cn=peercred,cn=external,cn=auth",
|
"cn=peercred,cn=external,cn=auth",
|
||||||
getegid(), geteuid() );
|
getegid(), geteuid() );
|
||||||
(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid,
|
(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid,
|
||||||
LDAP_PVT_SASL_LOCAL_SSF );
|
LDAP_PVT_SASL_LOCAL_SSF );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* (re)set security properties */
|
/* (re)set security properties */
|
||||||
sasl_setprop( ctx, SASL_SEC_PROPS,
|
sasl_setprop( ctx, SASL_SEC_PROPS,
|
||||||
&ld->ld_options.ldo_sasl_secprops );
|
&ld->ld_options.ldo_sasl_secprops );
|
||||||
|
|
||||||
ccred.bv_val = NULL;
|
ccred.bv_val = NULL;
|
||||||
ccred.bv_len = 0;
|
ccred.bv_len = 0;
|
||||||
|
mech = NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
saslrc = sasl_client_start( ctx,
|
saslrc = sasl_client_start( ctx,
|
||||||
mechs,
|
mechs,
|
||||||
#if SASL_VERSION_MAJOR < 2
|
#if SASL_VERSION_MAJOR < 2
|
||||||
NULL,
|
NULL,
|
||||||
#endif
|
#endif
|
||||||
&prompts,
|
&prompts,
|
||||||
(SASL_CONST char **)&ccred.bv_val,
|
(SASL_CONST char **)&ccred.bv_val,
|
||||||
&credlen,
|
&credlen,
|
||||||
&mech );
|
&mech );
|
||||||
|
|
||||||
if( pmech == NULL && mech != NULL ) {
|
if( pmech == NULL && mech != NULL ) {
|
||||||
pmech = mech;
|
pmech = mech;
|
||||||
|
|
||||||
if( flags != LDAP_SASL_QUIET ) {
|
if( flags != LDAP_SASL_QUIET ) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"SASL/%s authentication started\n",
|
"SASL/%s authentication started\n",
|
||||||
pmech );
|
pmech );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( saslrc == SASL_INTERACT ) {
|
if( saslrc == SASL_INTERACT ) {
|
||||||
int res;
|
int res;
|
||||||
if( !interact ) break;
|
if( !interact ) break;
|
||||||
res = (interact)( ld, flags, defaults, prompts );
|
res = (interact)( ld, flags, defaults, prompts );
|
||||||
|
|
||||||
if( res != LDAP_SUCCESS ) break;
|
if( res != LDAP_SUCCESS ) break;
|
||||||
}
|
}
|
||||||
} while ( saslrc == SASL_INTERACT );
|
*rmech = mech;
|
||||||
|
} while ( saslrc == SASL_INTERACT );
|
||||||
|
|
||||||
ccred.bv_len = credlen;
|
} else {
|
||||||
|
/* continuing an in-progress Bind */
|
||||||
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
|
struct berval *scred = NULL;
|
||||||
rc = ld->ld_errno = sasl_err2ldap( saslrc );
|
|
||||||
#if SASL_VERSION_MAJOR >= 2
|
|
||||||
if ( ld->ld_error ) {
|
|
||||||
LDAP_FREE( ld->ld_error );
|
|
||||||
}
|
|
||||||
ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) );
|
|
||||||
#endif
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
struct berval *scred;
|
|
||||||
unsigned credlen;
|
|
||||||
|
|
||||||
scred = NULL;
|
scred = NULL;
|
||||||
|
rc = ldap_parse_sasl_bind_result( ld, result, &scred, 0 );
|
||||||
|
if ( rc != LDAP_SUCCESS )
|
||||||
|
goto done;
|
||||||
|
|
||||||
rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls,
|
rc = ldap_result2error( ld, result, 0 );
|
||||||
&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 ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
|
||||||
if( scred ) {
|
if( scred ) {
|
||||||
/* and server provided us with data? */
|
/* and server provided us with data? */
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
|
"ldap_int_sasl_bind: rc=%d len=%ld\n",
|
||||||
rc, saslrc, scred ? (long) scred->bv_len : -1L );
|
rc, scred ? (long) scred->bv_len : -1L, 0 );
|
||||||
ber_bvfree( scred );
|
ber_bvfree( scred );
|
||||||
scred = NULL;
|
scred = NULL;
|
||||||
}
|
}
|
||||||
rc = ld->ld_errno;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
|
ctx = ld->ld_defconn->lconn_sasl_authctx;
|
||||||
/* we're done, no need to step */
|
mech = *rmech;
|
||||||
if( scred ) {
|
|
||||||
/* but we got additional data? */
|
|
||||||
#define KLUDGE_FOR_MSAD
|
|
||||||
#ifdef KLUDGE_FOR_MSAD
|
|
||||||
/*
|
|
||||||
* MSAD provides empty additional data in violation of LDAP
|
|
||||||
* technical specifications. As no existing SASL mechanism
|
|
||||||
* allows empty data with an outcome message, just ignore it
|
|
||||||
* for now. Hopefully MS will fix their bug before someone
|
|
||||||
* defines a mechanism with possibly empty additional data.
|
|
||||||
*/
|
|
||||||
if( scred->bv_len == 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"ldap_int_sasl_bind: ignoring "
|
|
||||||
" bogus empty data provided with SASL outcome message.\n",
|
|
||||||
rc, saslrc, scred->bv_len );
|
|
||||||
ber_bvfree( scred );
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
|
|
||||||
rc, saslrc, scred->bv_len );
|
|
||||||
rc = ld->ld_errno = LDAP_LOCAL_ERROR;
|
|
||||||
ber_bvfree( scred );
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if( ! scred ) {
|
if( ! scred ) {
|
||||||
/* no data! */
|
/* no data! */
|
||||||
|
|
@ -632,36 +589,42 @@ ldap_int_sasl_bind(
|
||||||
}
|
}
|
||||||
} while ( saslrc == SASL_INTERACT );
|
} while ( saslrc == SASL_INTERACT );
|
||||||
|
|
||||||
ccred.bv_len = credlen;
|
|
||||||
ber_bvfree( scred );
|
ber_bvfree( scred );
|
||||||
|
}
|
||||||
|
|
||||||
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
|
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
|
||||||
ld->ld_errno = sasl_err2ldap( saslrc );
|
rc = ld->ld_errno = sasl_err2ldap( saslrc );
|
||||||
#if SASL_VERSION_MAJOR >= 2
|
|
||||||
if ( ld->ld_error ) {
|
|
||||||
LDAP_FREE( ld->ld_error );
|
|
||||||
}
|
|
||||||
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 ) goto done;
|
|
||||||
|
|
||||||
if ( saslrc != SASL_OK ) {
|
|
||||||
#if SASL_VERSION_MAJOR >= 2
|
#if SASL_VERSION_MAJOR >= 2
|
||||||
if ( ld->ld_error ) {
|
if ( ld->ld_error ) {
|
||||||
LDAP_FREE( ld->ld_error );
|
LDAP_FREE( ld->ld_error );
|
||||||
}
|
}
|
||||||
ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) );
|
ld->ld_error = LDAP_STRDUP( sasl_errdetail( ctx ) );
|
||||||
#endif
|
#endif
|
||||||
rc = ld->ld_errno = sasl_err2ldap( saslrc );
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccred.bv_len = credlen;
|
||||||
|
|
||||||
|
/* Always send a request on first Bind; only send subsequent if
|
||||||
|
* saslrc == SASL_CONTINUE
|
||||||
|
*/
|
||||||
|
if ( !result || saslrc == SASL_CONTINUE ) {
|
||||||
|
rc = ldap_sasl_bind( ld, dn, mech, &ccred, sctrls, cctrls, msgid );
|
||||||
|
|
||||||
|
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;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Conversation was completed successfully by now */
|
||||||
if( flags != LDAP_SASL_QUIET ) {
|
if( flags != LDAP_SASL_QUIET ) {
|
||||||
|
char *data;
|
||||||
saslrc = sasl_getprop( ctx, SASL_USERNAME,
|
saslrc = sasl_getprop( ctx, SASL_USERNAME,
|
||||||
(SASL_CONST void **)(char *) &data );
|
(SASL_CONST void **)(char *) &data );
|
||||||
if( saslrc == SASL_OK && data && *data ) {
|
if( saslrc == SASL_OK && data && *data ) {
|
||||||
|
|
@ -677,6 +640,7 @@ ldap_int_sasl_bind(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssf = NULL;
|
||||||
saslrc = sasl_getprop( ctx, SASL_SSF, (SASL_CONST void **)(char *) &ssf );
|
saslrc = sasl_getprop( ctx, SASL_SSF, (SASL_CONST void **)(char *) &ssf );
|
||||||
if( saslrc == SASL_OK ) {
|
if( saslrc == SASL_OK ) {
|
||||||
if( flags != LDAP_SASL_QUIET ) {
|
if( flags != LDAP_SASL_QUIET ) {
|
||||||
|
|
@ -686,7 +650,7 @@ ldap_int_sasl_bind(
|
||||||
|
|
||||||
if( ssf && *ssf ) {
|
if( ssf && *ssf ) {
|
||||||
if ( ld->ld_defconn->lconn_sasl_sockctx ) {
|
if ( ld->ld_defconn->lconn_sasl_sockctx ) {
|
||||||
oldctx = ld->ld_defconn->lconn_sasl_sockctx;
|
sasl_conn_t *oldctx = ld->ld_defconn->lconn_sasl_sockctx;
|
||||||
sasl_dispose( &oldctx );
|
sasl_dispose( &oldctx );
|
||||||
ldap_pvt_sasl_remove( ld->ld_defconn->lconn_sb );
|
ldap_pvt_sasl_remove( ld->ld_defconn->lconn_sb );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -685,7 +685,10 @@ LDAP_F (int) ldap_int_sasl_bind LDAP_P((
|
||||||
/* should be passed in client controls */
|
/* should be passed in client controls */
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
LDAP_SASL_INTERACT_PROC *interact,
|
LDAP_SASL_INTERACT_PROC *interact,
|
||||||
void *defaults ));
|
void *defaults,
|
||||||
|
LDAPMessage *result,
|
||||||
|
const char **rmech,
|
||||||
|
int *msgid ));
|
||||||
|
|
||||||
/* in schema.c */
|
/* in schema.c */
|
||||||
LDAP_F (char *) ldap_int_parse_numericoid LDAP_P((
|
LDAP_F (char *) ldap_int_parse_numericoid LDAP_P((
|
||||||
|
|
|
||||||
|
|
@ -401,15 +401,16 @@ ldap_pvt_sasl_getmechs ( LDAP *ld, char **pmechlist )
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ldap_sasl_interactive_bind_s - interactive SASL authentication
|
* ldap_sasl_interactive_bind - interactive SASL authentication
|
||||||
*
|
*
|
||||||
* This routine uses interactive callbacks.
|
* This routine uses interactive callbacks.
|
||||||
*
|
*
|
||||||
* LDAP_SUCCESS is returned upon success, the ldap error code
|
* LDAP_SUCCESS is returned upon success, the ldap error code
|
||||||
* otherwise.
|
* otherwise. LDAP_SASL_BIND_IN_PROGRESS is returned if further
|
||||||
|
* calls are needed.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ldap_sasl_interactive_bind_s(
|
ldap_sasl_interactive_bind(
|
||||||
LDAP *ld,
|
LDAP *ld,
|
||||||
LDAP_CONST char *dn, /* usually NULL */
|
LDAP_CONST char *dn, /* usually NULL */
|
||||||
LDAP_CONST char *mechs,
|
LDAP_CONST char *mechs,
|
||||||
|
|
@ -417,10 +418,13 @@ ldap_sasl_interactive_bind_s(
|
||||||
LDAPControl **clientControls,
|
LDAPControl **clientControls,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
LDAP_SASL_INTERACT_PROC *interact,
|
LDAP_SASL_INTERACT_PROC *interact,
|
||||||
void *defaults )
|
void *defaults,
|
||||||
|
LDAPMessage *result,
|
||||||
|
const char **rmech,
|
||||||
|
int *msgid )
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
char *smechs = NULL;
|
char *smechs = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
#if defined( HAVE_CYRUS_SASL )
|
#if defined( HAVE_CYRUS_SASL )
|
||||||
LDAP_MUTEX_LOCK( &ldap_int_sasl_mutex );
|
LDAP_MUTEX_LOCK( &ldap_int_sasl_mutex );
|
||||||
|
|
@ -437,6 +441,9 @@ ldap_sasl_interactive_bind_s(
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* First time */
|
||||||
|
if ( !result ) {
|
||||||
|
|
||||||
#ifdef HAVE_CYRUS_SASL
|
#ifdef HAVE_CYRUS_SASL
|
||||||
if( mechs == NULL || *mechs == '\0' ) {
|
if( mechs == NULL || *mechs == '\0' ) {
|
||||||
mechs = ld->ld_options.ldo_def_sasl_mech;
|
mechs = ld->ld_options.ldo_def_sasl_mech;
|
||||||
|
|
@ -460,10 +467,10 @@ ldap_sasl_interactive_bind_s(
|
||||||
"ldap_sasl_interactive_bind_s: user selected: %s\n",
|
"ldap_sasl_interactive_bind_s: user selected: %s\n",
|
||||||
mechs, 0, 0 );
|
mechs, 0, 0 );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
rc = ldap_int_sasl_bind( ld, dn, mechs,
|
rc = ldap_int_sasl_bind( ld, dn, mechs,
|
||||||
serverControls, clientControls,
|
serverControls, clientControls,
|
||||||
flags, interact, defaults );
|
flags, interact, defaults, result, rmech, msgid );
|
||||||
|
|
||||||
done:
|
done:
|
||||||
#if defined( HAVE_CYRUS_SASL )
|
#if defined( HAVE_CYRUS_SASL )
|
||||||
|
|
@ -474,6 +481,51 @@ done:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ldap_sasl_interactive_bind_s - interactive SASL authentication
|
||||||
|
*
|
||||||
|
* This routine uses interactive callbacks.
|
||||||
|
*
|
||||||
|
* LDAP_SUCCESS is returned upon success, the ldap error code
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ldap_sasl_interactive_bind_s(
|
||||||
|
LDAP *ld,
|
||||||
|
LDAP_CONST char *dn, /* usually NULL */
|
||||||
|
LDAP_CONST char *mechs,
|
||||||
|
LDAPControl **serverControls,
|
||||||
|
LDAPControl **clientControls,
|
||||||
|
unsigned flags,
|
||||||
|
LDAP_SASL_INTERACT_PROC *interact,
|
||||||
|
void *defaults )
|
||||||
|
{
|
||||||
|
const char *rmech = NULL;
|
||||||
|
LDAPMessage *result = NULL;
|
||||||
|
int rc, msgid;
|
||||||
|
|
||||||
|
do {
|
||||||
|
rc = ldap_sasl_interactive_bind( ld, dn, mechs,
|
||||||
|
serverControls, clientControls,
|
||||||
|
flags, interact, defaults, result, &rmech, &msgid );
|
||||||
|
|
||||||
|
if ( rc != LDAP_SASL_BIND_IN_PROGRESS )
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef LDAP_CONNECTIONLESS
|
||||||
|
if (LDAP_IS_UDP(ld)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1 || !result ) {
|
||||||
|
return( ld->ld_errno ); /* ldap_result sets ld_errno */
|
||||||
|
}
|
||||||
|
} while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CYRUS_SASL
|
#ifdef HAVE_CYRUS_SASL
|
||||||
|
|
||||||
#ifdef HAVE_SASL_SASL_H
|
#ifdef HAVE_SASL_SASL_H
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue