X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-meta%2Fbind.c;h=acfc69577cecd577ba97c1279eae8e2f31d6dccb;hb=caf751fbb20fbccf535b900df1dabef0f40e0222;hp=880835349bb5938bdb4e659281903c7f7e33d50e;hpb=7d7f0e1d564587917590c7404fbfd0fccf6115ab;p=openldap diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 880835349b..acfc69577c 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1999-2009 The OpenLDAP Foundation. + * Copyright 1999-2012 The OpenLDAP Foundation. * Portions Copyright 2001-2003 Pierangelo Masarati. * Portions Copyright 1999-2003 Howard Chu. * All rights reserved. @@ -33,8 +33,6 @@ #include "slap.h" #include "../back-ldap/back-ldap.h" #include "back-meta.h" -#undef ldap_debug /* silence a warning in ldap-int.h */ -#include "../../../libraries/libldap/ldap-int.h" #include "lutil_ldap.h" @@ -44,7 +42,8 @@ meta_back_proxy_authz_bind( int candidate, Operation *op, SlapReply *rs, - ldap_back_send_t sendok ); + ldap_back_send_t sendok, + int dolock ); static int meta_back_single_bind( @@ -180,7 +179,7 @@ meta_back_bind( Operation *op, SlapReply *rs ) } - (void)meta_back_proxy_authz_bind( mc, i, op, rs, LDAP_BACK_DONTSEND ); + (void)meta_back_proxy_authz_bind( mc, i, op, rs, LDAP_BACK_DONTSEND, 1 ); lerr = rs->sr_err; } else { @@ -307,7 +306,8 @@ meta_back_bind_op_result( metaconn_t *mc, int candidate, int msgid, - ldap_back_send_t sendok ) + ldap_back_send_t sendok, + int dolock ) { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metatarget_t *mt = mi->mi_targets[ candidate ]; @@ -386,7 +386,9 @@ retry:; /* don't let anyone else use this handler, * because there's a pending bind that will not * be acknowledged */ - ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + if ( dolock) { + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + } assert( LDAP_BACK_CONN_BINDING( msc ) ); #ifdef DEBUG_205 @@ -395,7 +397,9 @@ retry:; #endif /* DEBUG_205 */ meta_clear_one_candidate( op, mc, candidate ); - ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); + if ( dolock ) { + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); + } rs->sr_err = timeout_err; rs->sr_text = timeout_text; @@ -425,6 +429,7 @@ retry:; if ( rc != LDAP_SUCCESS ) { rs->sr_err = rc; } + rs->sr_err = slap_map_api2result( rs ); break; } } @@ -517,7 +522,7 @@ meta_back_single_bind( mi->mi_ldap_extra->controls_free( op, rs, &ctrls ); - meta_back_bind_op_result( op, rs, mc, candidate, msgid, LDAP_BACK_DONTSEND ); + meta_back_bind_op_result( op, rs, mc, candidate, msgid, LDAP_BACK_DONTSEND, 1 ); if ( rs->sr_err != LDAP_SUCCESS ) { goto return_results; } @@ -528,7 +533,7 @@ meta_back_single_bind( * bind with the configured identity assertion */ /* NOTE: use with care */ if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { - meta_back_proxy_authz_bind( mc, candidate, op, rs, LDAP_BACK_SENDERR ); + meta_back_proxy_authz_bind( mc, candidate, op, rs, LDAP_BACK_SENDERR, 1 ); if ( !LDAP_BACK_CONN_ISBOUND( msc ) ) { goto return_results; } @@ -585,7 +590,6 @@ meta_back_single_dobind( metatarget_t *mt = mi->mi_targets[ candidate ]; metaconn_t *mc = *mcp; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; - static struct berval cred = BER_BVC( "" ); int msgid; assert( !LDAP_BACK_CONN_ISBOUND( msc ) ); @@ -598,15 +602,25 @@ meta_back_single_dobind( ( LDAP_BACK_CONN_ISPRIV( mc ) && dn_match( &msc->msc_bound_ndn, &mt->mt_idassert_authcDN ) ) || ( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) ) { - (void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok ); + (void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok, dolock ); } else { + char *binddn = ""; + struct berval cred = BER_BVC( "" ); + + /* use credentials if available */ + if ( !BER_BVISNULL( &msc->msc_bound_ndn ) + && !BER_BVISNULL( &msc->msc_cred ) ) + { + binddn = msc->msc_bound_ndn.bv_val; + cred = msc->msc_cred; + } /* FIXME: should we check if at least some of the op->o_ctrls * can/should be passed? */ for (;;) { rs->sr_err = ldap_sasl_bind( msc->msc_ld, - "", LDAP_SASL_SIMPLE, &cred, + binddn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, &msgid ); if ( rs->sr_err != LDAP_X_CONNECTING ) { break; @@ -614,16 +628,30 @@ meta_back_single_dobind( ldap_pvt_thread_yield(); } - rs->sr_err = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok ); + rs->sr_err = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok, dolock ); + + /* if bind succeeded, but anonymous, clear msc_bound_ndn */ + if ( rs->sr_err != LDAP_SUCCESS || binddn[0] == '\0' ) { + if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) { + ber_memfree( msc->msc_bound_ndn.bv_val ); + BER_BVZERO( &msc->msc_bound_ndn ); + } + + if ( !BER_BVISNULL( &msc->msc_cred ) ) { + memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len ); + ber_memfree( msc->msc_cred.bv_val ); + BER_BVZERO( &msc->msc_cred ); + } + } } if ( rs->sr_err != LDAP_SUCCESS ) { if ( dolock ) { ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); } - LDAP_BACK_CONN_BINDING_CLEAR( msc ); + LDAP_BACK_CONN_BINDING_CLEAR( msc ); if ( META_BACK_ONERR_STOP( mi ) ) { - LDAP_BACK_CONN_TAINTED_SET( mc ); + LDAP_BACK_CONN_TAINTED_SET( mc ); meta_back_release_conn_lock( mi, mc, 0 ); *mcp = NULL; } @@ -746,8 +774,8 @@ retry_binding:; if ( mc != NULL ) { ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); LDAP_BACK_CONN_BINDING_CLEAR( msc ); + meta_back_release_conn_lock( mi, mc, 0 ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); - meta_back_release_conn( mi, mc ); } return 0; @@ -1042,10 +1070,12 @@ retry:; rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err, &matched, &text, &refs, &ctrls, 1 ); res = NULL; - rs->sr_text = text; - if ( rc != LDAP_SUCCESS ) { + if ( rc == LDAP_SUCCESS ) { + rs->sr_text = text; + } else { rs->sr_err = rc; } + rs->sr_err = slap_map_api2result( rs ); /* RFC 4511: referrals can only appear * if result code is LDAP_REFERRAL */ @@ -1121,6 +1151,10 @@ retry:; char *xtext = NULL; char *xmatched = NULL; + if ( msc->msc_ld == NULL ) { + continue; + } + rs->sr_err = LDAP_SUCCESS; ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err ); @@ -1306,6 +1340,7 @@ meta_back_proxy_authz_cred( } else { ndn = op->o_ndn; } + rs->sr_err = LDAP_SUCCESS; /* * FIXME: we need to let clients use proxyAuthz @@ -1511,11 +1546,22 @@ meta_back_proxy_authz_cred( } done:; + + if ( !BER_BVISEMPTY( binddn ) ) { + LDAP_BACK_CONN_ISIDASSERT_SET( msc ); + } + return rs->sr_err; } static int -meta_back_proxy_authz_bind( metaconn_t *mc, int candidate, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) +meta_back_proxy_authz_bind( + metaconn_t *mc, + int candidate, + Operation *op, + SlapReply *rs, + ldap_back_send_t sendok, + int dolock ) { metainfo_t *mi = (metainfo_t *)op->o_bd->be_private; metatarget_t *mt = mi->mi_targets[ candidate ]; @@ -1541,7 +1587,7 @@ meta_back_proxy_authz_bind( metaconn_t *mc, int candidate, Operation *op, SlapRe } ldap_pvt_thread_yield(); } - rc = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok ); + rc = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok, dolock ); if ( rc == LDAP_SUCCESS ) { /* set rebind stuff in case of successful proxyAuthz bind, * so that referral chasing is attempted using the right