ldap_back_proxy_authz_bind( lc, op, rs, LDAP_BACK_SENDERR );
if ( !LDAP_BACK_CONN_ISBOUND( lc ) ) {
rc = 1;
- goto done;
}
+ goto done;
}
+ /* rebind is now done inside ldap_back_proxy_authz_bind()
+ * in case of success */
LDAP_BACK_CONN_ISBOUND_SET( lc );
ber_dupbv( &lc->lc_bound_ndn, &op->o_req_ndn );
} else {
BER_BVZERO( &lc->lc_cred );
BER_BVZERO( &lc->lc_bound_ndn );
-#if 0
- /* FIXME: if we set lc_bound_ndn = o_ndn
- * we end up with a bind with DN but no password! */
if ( !BER_BVISEMPTY( &op->o_ndn )
&& SLAP_IS_AUTHZ_BACKEND( op ) )
{
ber_dupbv( &lc->lc_bound_ndn, &op->o_ndn );
}
-#endif
}
#ifdef HAVE_TLS
* It allows to use SASL bind and yet proxyAuthz users
*/
if ( op->o_conn != NULL &&
- !op->o_do_not_cache &&
- ( BER_BVISNULL( &lc->lc_bound_ndn ) ||
- ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
+ !op->o_do_not_cache &&
+ ( BER_BVISNULL( &lc->lc_bound_ndn ) ||
+ ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
{
(void)ldap_back_proxy_authz_bind( lc, op, rs, sendok );
goto done;
retry:;
rs->sr_err = ldap_sasl_bind( lc->lc_ld,
- lc->lc_bound_ndn.bv_val,
+ BER_BVISNULL( &lc->lc_cred ) ? "" : lc->lc_bound_ndn.bv_val,
LDAP_SASL_SIMPLE, &lc->lc_cred,
NULL, NULL, &msgid );
/* FIXME: add checks on the URL/identity? */
- return ldap_sasl_bind_s( ld, lc->lc_bound_ndn.bv_val,
+ return ldap_sasl_bind_s( ld,
+ BER_BVISNULL( &lc->lc_cred ) ? "" : lc->lc_bound_ndn.bv_val,
LDAP_SASL_SIMPLE, &lc->lc_cred, NULL, NULL, NULL );
}
return LDAP_SUCCESS;
}
+int
+ldap_back_cancel(
+ ldapconn_t *lc,
+ Operation *op,
+ SlapReply *rs,
+ ber_int_t msgid,
+ ldap_back_send_t sendok )
+{
+ ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
+
+ /* default behavior */
+ if ( LDAP_BACK_ABANDON( li ) ) {
+ return ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
+ }
+
+ if ( LDAP_BACK_IGNORE( li ) ) {
+ return LDAP_SUCCESS;
+ }
+
+ if ( LDAP_BACK_CANCEL( li ) ) {
+ /* FIXME: asynchronous? */
+ return ldap_cancel_s( lc->lc_ld, msgid, NULL, NULL );
+ }
+
+ assert( 0 );
+
+ return LDAP_OTHER;
+}
+
int
ldap_back_op_result(
ldapconn_t *lc,
char *match = NULL;
LDAPMessage *res = NULL;
char *text = NULL;
+ char **refs = NULL;
+ LDAPControl **ctrls = NULL;
#define ERR_OK(err) ((err) == LDAP_SUCCESS || (err) == LDAP_COMPARE_FALSE || (err) == LDAP_COMPARE_TRUE)
rs->sr_text = NULL;
rs->sr_matched = NULL;
+ rs->sr_ref = NULL;
+ rs->sr_ctrls = NULL;
/* if the error recorded in the reply corresponds
* to a successful state, get the error from the
switch ( rc ) {
case 0:
if ( timeout ) {
- (void)ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
+ (void)ldap_back_cancel( lc, op, rs, msgid, sendok );
rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
rs->sr_text = "Operation timed out";
* LDAP_COMPARE_{TRUE|FALSE}) */
default:
rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
- &match, &text, NULL, NULL, 1 );
+ &match, &text, &refs, &ctrls, 1 );
rs->sr_text = text;
if ( rc != LDAP_SUCCESS ) {
rs->sr_err = rc;
}
+ if ( refs != NULL ) {
+ int i;
+
+ for ( i = 0; refs[ i ] != NULL; i++ )
+ /* count */ ;
+ rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ),
+ op->o_tmpmemctx );
+ for ( i = 0; refs[ i ] != NULL; i++ ) {
+ ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] );
+ }
+ BER_BVZERO( &rs->sr_ref[ i ] );
+ }
+ if ( ctrls != NULL ) {
+ rs->sr_ctrls = ctrls;
+ }
}
}
}
}
if ( op->o_conn &&
- ( ( sendok & LDAP_BACK_SENDOK )
- || ( ( sendok & LDAP_BACK_SENDERR ) && rs->sr_err != LDAP_SUCCESS ) ) )
+ ( ( sendok & LDAP_BACK_SENDOK )
+ || ( ( sendok & LDAP_BACK_SENDERR ) && rs->sr_err != LDAP_SUCCESS ) ) )
{
send_ldap_result( op, rs );
}
ldap_memfree( text );
}
rs->sr_text = NULL;
+ if ( rs->sr_ref ) {
+ assert( refs != NULL );
+ ber_memvfree( (void **)refs );
+ op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx );
+ rs->sr_ref = NULL;
+ }
+ if ( ctrls ) {
+ assert( rs->sr_ctrls != NULL );
+ ldap_controls_free( ctrls );
+ rs->sr_ctrls = NULL;
+ }
return( ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err );
}
switch ( li->li_idassert_authmethod ) {
case LDAP_AUTH_NONE:
- LDAP_BACK_CONN_ISBOUND_SET( lc );
- goto done;
+ rc = LDAP_SUCCESS;
+ break;
case LDAP_AUTH_SIMPLE:
rs->sr_err = ldap_sasl_bind( lc->lc_ld,
binddn.bv_val, LDAP_SASL_SIMPLE,
&bindcred, NULL, NULL, &msgid );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 0, sendok );
break;
default:
goto done;
}
- rc = ldap_back_op_result( lc, op, rs, msgid, 0, sendok );
if ( rc == LDAP_SUCCESS ) {
+ /* set rebind stuff in case of successful proxyAuthz bind,
+ * so that referral chasing is attempted using the right
+ * identity */
LDAP_BACK_CONN_ISBOUND_SET( lc );
+ ber_dupbv( &lc->lc_bound_ndn, &binddn );
+
+ if ( LDAP_BACK_SAVECRED( li ) ) {
+ if ( !BER_BVISNULL( &lc->lc_cred ) ) {
+ memset( lc->lc_cred.bv_val, 0,
+ lc->lc_cred.bv_len );
+ }
+ ber_bvreplace( &lc->lc_cred, &bindcred );
+ ldap_set_rebind_proc( lc->lc_ld, li->li_rebind_f, lc );
+ }
}
done:;
return LDAP_BACK_CONN_ISBOUND( lc );