retry:;
rc = ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res );
if ( rc < 0 ) {
- rc = LDAP_OTHER;
+ rc = LDAP_UNAVAILABLE;
} else if ( rc == 0 ) {
if ( retries != LDAP_BACK_RETRY_NEVER ) {
LDAP_BACK_TV_SET( &tv );
goto retry;
}
- rc = LDAP_OTHER;
+ rc = LDAP_UNAVAILABLE;
} else if ( rc == LDAP_RES_EXTENDED ) {
struct berval *data = NULL;
rc = ldap_install_tls( ld );
} else if ( rc == LDAP_REFERRAL ) {
- rc = LDAP_OTHER;
+ rc = LDAP_UNWILLING_TO_PERFORM;
*text = "unwilling to chase referral returned by Start TLS exop";
}
/* Set LDAP version. This will always succeed: If the client
* bound with a particular version, then so can we.
*/
+ if ( vers == 0 ) {
+ /* assume it's an internal op; set to LDAPv3 */
+ vers = LDAP_VERSION3;
+ }
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers );
/* automatically chase referrals ("[dont-]chase-referrals" statement) */
}
} else {
- Debug( LDAP_DEBUG_TRACE,
- "=>ldap_back_getconn: conn %p fetched (refcnt=%u)\n",
- (void *)lc, refcnt, 0 );
+ if ( li->li_idle_timeout != 0 && op->o_time > lc->lc_time + li->li_idle_timeout ) {
+ /* in case of failure, it frees/taints lc and sets it to NULL */
+ if ( ldap_back_retry( &lc, op, rs, sendok ) ) {
+ lc = NULL;
+ }
+ }
+
+ if ( lc ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "=>ldap_back_getconn: conn %p fetched (refcnt=%u)\n",
+ (void *)lc, refcnt, 0 );
+ }
+ }
+
+ if ( li->li_idle_timeout && lc ) {
+ lc->lc_time = op->o_time;
}
done:;
retry:;
/* if result parsing fails, note the failure reason */
- rc = ldap_result( lc->lc_ld, msgid, 1, &tv, &res );
+ rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
switch ( rc ) {
case 0:
if ( timeout ) {
int rc = 0;
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
+ assert( lcp != NULL );
+ assert( *lcp != NULL );
+
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
if ( (*lcp)->lc_refcnt == 1 ) {
/* lc here must be the regular lc, reset and ready for init */
rc = ldap_back_prepare_conn( lcp, op, rs, sendok );
- if ( rc == LDAP_SUCCESS ) {
+ if ( rc != LDAP_SUCCESS ) {
+ rc = 0;
+ *lcp = NULL;
+
+ } else {
rc = ldap_back_dobind_int( *lcp, op, rs, sendok, 0, 0 );
if ( rc == 0 ) {
*lcp = NULL;
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
struct berval binddn = slap_empty_bv;
struct berval bindcred = slap_empty_bv;
+ struct berval ndn;
int dobind = 0;
int msgid;
int rc;
+ if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ ndn = op->o_conn->c_ndn;
+
+ } else {
+ ndn = op->o_ndn;
+ }
+
/*
* FIXME: we need to let clients use proxyAuthz
* otherwise we cannot do symmetric pools of servers;
* is authorized */
switch ( li->li_idassert_mode ) {
case LDAP_BACK_IDASSERT_LEGACY:
- if ( !BER_BVISNULL( &op->o_conn->c_ndn ) && !BER_BVISEMPTY( &op->o_conn->c_ndn ) ) {
+ if ( !BER_BVISNULL( &ndn ) && !BER_BVISEMPTY( &ndn ) ) {
if ( !BER_BVISNULL( &li->li_idassert_authcDN ) && !BER_BVISEMPTY( &li->li_idassert_authcDN ) )
{
binddn = li->li_idassert_authcDN;
if ( li->li_idassert_authz && !be_isroot( op ) ) {
struct berval authcDN;
- if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ if ( BER_BVISNULL( &ndn ) ) {
authcDN = slap_empty_bv;
} else {
- authcDN = op->o_conn->c_ndn;
+ authcDN = ndn;
}
rs->sr_err = slap_sasl_matches( op, li->li_idassert_authz,
&authcDN, &authcDN );
break;
case LDAP_BACK_IDASSERT_SELF:
- if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ if ( BER_BVISNULL( &ndn ) ) {
/* connection is not authc'd, so don't idassert */
BER_BVSTR( &authzID, "dn:" );
break;
}
- authzID.bv_len = STRLENOF( "dn:" ) + op->o_conn->c_ndn.bv_len;
+ authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len;
authzID.bv_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx );
AC_MEMCPY( authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
AC_MEMCPY( authzID.bv_val + STRLENOF( "dn:" ),
- op->o_conn->c_ndn.bv_val, op->o_conn->c_ndn.bv_len + 1 );
+ ndn.bv_val, ndn.bv_len + 1 );
freeauthz = 1;
break;
LDAPControl **ctrls = NULL;
int i = 0,
mode;
- struct berval assertedID;
+ struct berval assertedID,
+ ndn;
*pctrls = NULL;
goto done;
}
+ if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ ndn = op->o_conn->c_ndn;
+
+ } else {
+ ndn = op->o_ndn;
+ }
+
if ( li->li_idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) {
if ( op->o_proxy_authz ) {
/*
goto done;
}
- if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ if ( BER_BVISNULL( &ndn ) ) {
goto done;
}
} else if ( li->li_idassert_authmethod == LDAP_AUTH_SASL ) {
if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ )
- /* && ( !BER_BVISNULL( &op->o_conn->c_ndn )
+ /* && ( !BER_BVISNULL( &ndn )
|| LDAP_BACK_CONN_ISBOUND( lc ) ) */ )
{
/* already asserted in SASL via native authz */
/* NOTE: the test on lc->lc_bound is used to trap
* native authorization of anonymous users,
- * since in that case op->o_conn->c_ndn is NULL */
+ * since in that case ndn is NULL */
goto done;
}
int rc;
struct berval authcDN;
- if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ if ( BER_BVISNULL( &ndn ) ) {
authcDN = slap_empty_bv;
} else {
- authcDN = op->o_conn->c_ndn;
+ authcDN = ndn;
}
rc = slap_sasl_matches( op, li->li_idassert_authz,
&authcDN, & authcDN );
if ( rc != LDAP_SUCCESS ) {
if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE )
{
- /* op->o_conn->c_ndn is not authorized
+ /* ndn is not authorized
* to use idassert */
return rc;
}
case LDAP_BACK_IDASSERT_SELF:
/* original behavior:
* assert the client's identity */
- if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ if ( BER_BVISNULL( &ndn ) ) {
assertedID = slap_empty_bv;
} else {
- assertedID = op->o_conn->c_ndn;
+ assertedID = ndn;
}
break;