sasl_conn_t *ctx;
sasl_interact_t *prompts = NULL;
unsigned credlen;
- struct berval ccred, *scred;
+ struct berval ccred;
ber_socket_t sd;
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n",
return ld->ld_errno;
}
- scred = NULL;
-
do {
+ struct berval *scred;
unsigned credlen;
- rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
+ scred = NULL;
- if ( rc == LDAP_SUCCESS ) {
- break;
- } else if ( rc != LDAP_SASL_BIND_IN_PROGRESS ) {
- if ( ccred.bv_val != NULL ) {
- LDAP_FREE( ccred.bv_val );
- }
- return ld->ld_errno;
- }
+ rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
if ( ccred.bv_val != NULL ) {
LDAP_FREE( ccred.bv_val );
ccred.bv_val = NULL;
}
+ if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
+ return ld->ld_errno;
+ }
+
+ if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
+ /* we're done, no need to step */
+ if( scred ) {
+ /* but server provided us with data! */
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
+ rc, saslrc, scred->bv_len );
+ ber_bvfree( scred );
+ return ld->ld_errno = LDAP_LOCAL_ERROR;
+ }
+ break;
+ }
+
do {
saslrc = sasl_client_step( ctx,
(scred == NULL) ? NULL : scred->bv_val,
}
} while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
- assert ( rc == LDAP_SUCCESS );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( saslrc != SASL_OK ) {
+ return ld->ld_errno = sasl_err2ldap( saslrc );
+ }
/* likely should add a quiet option */
ber_tag_t tag;
ber_int_t msgid;
- Debug( LDAP_DEBUG_TRACE, "send_ldap_sasl %ld\n",
- (long) err, NULL, NULL );
+ Debug( LDAP_DEBUG_TRACE, "send_ldap_sasl: err=%ld len=%ld\n",
+ (long) err, cred ? cred->bv_len : -1, NULL );
tag = req2res( op->o_tag );
msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
}
send_ldap_sasl( conn, op, rc = LDAP_SUCCESS,
- NULL, NULL, NULL, NULL, &response );
+ NULL, NULL, NULL, NULL,
+ response.bv_len ? &response : NULL );
}
} else if ( sc == SASL_CONTINUE ) {