From cec460d3eedfd7cb9de65dfd655fd392ff4656ab Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Wed, 23 Jun 2010 00:13:50 +0000 Subject: [PATCH] make sure non-anonymous bind uses DN and creds (ITS#6574) --- servers/slapd/back-meta/bind.c | 37 ++++++++++++++++++++++++++++++---- servers/slapd/back-meta/conn.c | 20 ++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 7c89bee189..55c088bd6b 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -586,7 +586,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 ) ); @@ -602,12 +601,22 @@ meta_back_single_dobind( (void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok ); } 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; @@ -616,15 +625,26 @@ meta_back_single_dobind( } rs->sr_err = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok ); + + /* if bind succeeded, but anonymous, clear msc_bound_ndn */ + if ( rs->sr_err == LDAP_SUCCESS ) { + if ( binddn[0] == '\0' && + !BER_BVISNULL( &msc->msc_bound_ndn ) && + !BER_BVISEMPTY( &msc->msc_bound_ndn ) ) + { + ber_memfree( msc->msc_bound_ndn.bv_val ); + BER_BVZERO( &msc->msc_bound_ndn ); + } + } } 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; } @@ -1124,6 +1144,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 ); @@ -1514,6 +1538,11 @@ meta_back_proxy_authz_cred( } done:; + + if ( !BER_BVISEMPTY( binddn ) ) { + LDAP_BACK_CONN_ISIDASSERT_SET( msc ); + } + return rs->sr_err; } diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index ca5b7932c3..c8fe33ae1c 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -572,6 +572,7 @@ retry:; } ber_bvreplace( &msc->msc_cred, &mt->mt_idassert_passwd ); } + LDAP_BACK_CONN_ISIDASSERT_SET( msc ); } else { ber_bvreplace( &msc->msc_bound_ndn, &slap_empty_bv ); @@ -685,6 +686,8 @@ meta_back_retry( assert( mc->mc_refcnt > 0 ); if ( mc->mc_refcnt == 1 ) { + struct berval save_cred; + if ( LogTest( LDAP_DEBUG_ANY ) ) { char buf[ SLAP_TEXT_BUFLEN ]; @@ -703,6 +706,11 @@ meta_back_retry( op->o_log_prefix, candidate, buf ); } + /* save credentials, if any, for later use; + * meta_clear_one_candidate() would free them */ + save_cred = msc->msc_cred; + BER_BVZERO( &msc->msc_cred ); + meta_clear_one_candidate( op, mc, candidate ); LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); @@ -712,6 +720,17 @@ meta_back_retry( rc = meta_back_init_one_conn( op, rs, mc, candidate, LDAP_BACK_CONN_ISPRIV( mc ), sendok, 0 ); + /* restore credentials, if any; + * meta_back_init_one_conn() restores msc_bound_ndn, if any; + * if no msc_bound_ndn is restored, destroy credentials */ + if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) { + msc->msc_cred = save_cred; + + } else if ( !BER_BVISNULL( &save_cred ) ) { + memset( save_cred.bv_val, 0, save_cred.bv_len ); + ber_memfree( save_cred.bv_val ); + } + /* restore the "binding" flag, in case */ if ( binding ) { LDAP_BACK_CONN_BINDING_SET( msc ); @@ -1095,6 +1114,7 @@ retry_lock:; } if ( mc != NULL ) { + /* move to tail of queue */ if ( mc != LDAP_TAILQ_LAST( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, metaconn_t, mc_q ) ) { -- 2.39.5