X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-meta%2Fbind.c;h=acfc69577cecd577ba97c1279eae8e2f31d6dccb;hb=caf751fbb20fbccf535b900df1dabef0f40e0222;hp=bcfd191526dab1b1c5069d27a7de04b14efb798b;hpb=f3eeb814584e3a0622ccff856fc78b5fcf9c8578;p=openldap diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index bcfd191526..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-2008 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 { @@ -223,9 +222,10 @@ meta_back_bind( Operation *op, SlapReply *rs ) while ( ( tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp ) ) != NULL ) { + assert( !LDAP_BACK_PCONN_ISPRIV( mc ) ); Debug( LDAP_DEBUG_TRACE, - "=>meta_back_bind: destroying conn %ld (refcnt=%u)\n", - LDAP_BACK_PCONN_ID( mc ), mc->mc_refcnt, 0 ); + "=>meta_back_bind: destroying conn %lu (refcnt=%u)\n", + mc->mc_conn->c_connid, mc->mc_refcnt, 0 ); if ( tmpmc->mc_refcnt != 0 ) { /* taint it */ @@ -306,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 ]; @@ -385,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 @@ -394,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; @@ -424,6 +429,7 @@ retry:; if ( rc != LDAP_SUCCESS ) { rs->sr_err = rc; } + rs->sr_err = slap_map_api2result( rs ); break; } } @@ -516,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; } @@ -527,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; } @@ -538,7 +544,7 @@ meta_back_single_bind( LDAP_BACK_CONN_ISBOUND_SET( msc ); mc->mc_authz_target = candidate; - if ( LDAP_BACK_SAVECRED( mi ) ) { + if ( META_BACK_TGT_SAVECRED( mt ) ) { if ( !BER_BVISNULL( &msc->msc_cred ) ) { memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len ); @@ -584,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 ) ); @@ -597,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; @@ -613,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; } @@ -660,11 +689,15 @@ meta_back_dobind( isroot = 1; } - Debug( LDAP_DEBUG_TRACE, - "%s meta_back_dobind: conn=%ld%s\n", - op->o_log_prefix, - LDAP_BACK_PCONN_ID( mc ), - isroot ? " (isroot)" : "" ); + if ( LogTest( LDAP_DEBUG_TRACE ) ) { + char buf[STRLENOF("4294967295U") + 1] = { 0 }; + mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) ); + + Debug( LDAP_DEBUG_TRACE, + "%s meta_back_dobind: conn=%s%s\n", + op->o_log_prefix, buf, + isroot ? " (isroot)" : "" ); + } /* * all the targets are bound as pseudoroot @@ -741,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; @@ -796,9 +829,14 @@ retry_ok:; } done:; - Debug( LDAP_DEBUG_TRACE, - "%s meta_back_dobind: conn=%ld bound=%d\n", - op->o_log_prefix, LDAP_BACK_PCONN_ID( mc ), bound ); + if ( LogTest( LDAP_DEBUG_TRACE ) ) { + char buf[STRLENOF("4294967295U") + 1] = { 0 }; + mi->mi_ldap_extra->connid2str( &mc->mc_base, buf, sizeof(buf) ); + + Debug( LDAP_DEBUG_TRACE, + "%s meta_back_dobind: conn=%s bound=%d\n", + op->o_log_prefix, buf, bound ); + } if ( bound == 0 ) { meta_back_release_conn( mi, mc ); @@ -953,9 +991,7 @@ meta_back_op_result( metatarget_t *mt = mi->mi_targets[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; -#define ERR_OK(err) ((err) == LDAP_SUCCESS || (err) == LDAP_COMPARE_FALSE || (err) == LDAP_COMPARE_TRUE) - - if ( ERR_OK( rs->sr_err ) ) { + if ( LDAP_ERR_OK( rs->sr_err ) ) { int rc; struct timeval tv; LDAPMessage *res = NULL; @@ -1034,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 */ @@ -1087,7 +1125,7 @@ retry:; /* if the error in the reply structure is not * LDAP_SUCCESS, try to map it from client * to server error */ - if ( !ERR_OK( rs->sr_err ) ) { + if ( !LDAP_ERR_OK( rs->sr_err ) ) { rs->sr_err = slap_map_api2result( rs ); /* internal ops ( op->o_conn == NULL ) @@ -1113,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 ); @@ -1206,9 +1248,17 @@ retry:; rs->sr_matched = matched; } - if ( op->o_conn && - ( ( sendok & LDAP_BACK_SENDOK ) - || ( ( sendok & LDAP_BACK_SENDERR ) && rs->sr_err != LDAP_SUCCESS ) ) ) + if ( rs->sr_err == LDAP_UNAVAILABLE ) { + if ( !( sendok & LDAP_BACK_RETRYING ) ) { + if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) { + if ( rs->sr_text == NULL ) rs->sr_text = "Proxy operation retry failed"; + send_ldap_result( op, rs ); + } + } + + } else if ( op->o_conn && + ( ( ( sendok & LDAP_BACK_SENDOK ) && LDAP_ERR_OK( rs->sr_err ) ) + || ( ( sendok & LDAP_BACK_SENDERR ) && !LDAP_ERR_OK( rs->sr_err ) ) ) ) { send_ldap_result( op, rs ); } @@ -1235,7 +1285,7 @@ retry:; rs->sr_ref = save_ref; rs->sr_ctrls = save_ctrls; - return( ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err ); + return( LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err ); } /* @@ -1290,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 @@ -1495,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 ]; @@ -1525,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 @@ -1533,7 +1595,7 @@ meta_back_proxy_authz_bind( metaconn_t *mc, int candidate, Operation *op, SlapRe LDAP_BACK_CONN_ISBOUND_SET( msc ); ber_bvreplace( &msc->msc_bound_ndn, &binddn ); - if ( LDAP_BACK_SAVECRED( mi ) ) { + if ( META_BACK_TGT_SAVECRED( mt ) ) { if ( !BER_BVISNULL( &msc->msc_cred ) ) { memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len ); @@ -1575,7 +1637,7 @@ meta_back_controls_add( LDAPControl **ctrls = NULL; /* set to the maximum number of controls this backend can add */ - LDAPControl c[ 2 ] = { 0 }; + LDAPControl c[ 2 ] = {{ 0 }}; int n = 0, i, j1 = 0, j2 = 0; *pctrls = NULL; @@ -1642,7 +1704,7 @@ meta_back_controls_add( goto done; } - assert( j1 + j1 <= sizeof( c )/sizeof(LDAPControl) ); + assert( j1 + j2 <= (int) (sizeof( c )/sizeof( c[0] )) ); if ( op->o_ctrls ) { for ( n = 0; op->o_ctrls[ n ]; n++ )