diff --git a/CHANGES b/CHANGES index 978072d572daa1c9de0ef179e7afd4833e139283..bf02dd1fa5768df1612bd6c27d54545dab06050d 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,7 @@ OpenLDAP 2.4.24 Engineering Fixed slapd-ndb to honor rootpw setting (ITS#6661) Fixed slapd-meta anon retry with failed auth method (ITS#6643) Fixed slapd-meta rebind proc (ITS#6665) + Fixed slapd-meta to correctly rebind as user (ITS#6574) Fixed slapd-null back-config support (ITS#6624) Fixed slapo-pcache callback freeing (ITS#6640) Fixed slapo-pcache to ignore undefined attrs (ITS#6600) diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 7c89bee1898bf2287c22f68dfee07c9d638f6663..55c088bd6b0de6ca1ed054ff1d774971a6d25ba9 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 ca5b7932c380ff1f616ccb30411261273ccb40d5..c8fe33ae1c2927b31113d3b49b46f5ff61191336 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 ) ) {