/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1999-2005 The OpenLDAP Foundation.
+ * Copyright 1999-2006 The OpenLDAP Foundation.
* Portions Copyright 2000-2003 Pierangelo Masarati.
* Portions Copyright 1999-2003 Howard Chu.
* All rights reserved.
int rc = 0;
ber_int_t msgid;
- lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
+ lc = ldap_back_getconn( op, rs, LDAP_BACK_BIND_SERR );
if ( !lc ) {
return rs->sr_err;
}
}
}
- /* Searches for a ldapconn in the avl tree */
- ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
+ /* Explicit Bind requests always get their own conn */
+ if ( sendok & LDAP_BACK_BINDING ) {
+ lc = NULL;
+ } else {
+ /* Searches for a ldapconn in the avl tree */
+retry_lock:
+ ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
- lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree,
- (caddr_t)&lc_curr, ldap_back_conn_cmp );
- if ( lc != NULL ) {
- refcnt = ++lc->lc_refcnt;
+ lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree,
+ (caddr_t)&lc_curr, ldap_back_conn_cmp );
+ if ( lc != NULL ) {
+ refcnt = ++lc->lc_refcnt;
+ /* Don't reuse connections while they're still binding */
+ if ( LDAP_BACK_CONN_BINDING( lc )) {
+ ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
}
- ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
/* Looks like we didn't get a bind. Open a new session... */
if ( lc == NULL ) {
if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
return NULL;
}
+ if ( sendok & LDAP_BACK_BINDING )
+ LDAP_BACK_CONN_BINDING_SET( lc );
lc->lc_conn = lc_curr.lc_conn;
ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
assert( lc->lc_refcnt > 0 );
lc->lc_refcnt--;
+ LDAP_BACK_CONN_BINDING_CLEAR( lc );
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
}
return rc;
}
+ while ( lc->lc_refcnt > 1 ) {
+ ldap_pvt_thread_yield();
+ if (( rc = LDAP_BACK_CONN_ISBOUND( lc )))
+ return rc;
+ }
+
/*
* FIXME: we need to let clients use proxyAuthz
* otherwise we cannot do symmetric pools of servers;
default:
/* NOTE: rootdn can always idassert */
- if ( li->li_idassert_authz && !be_isroot( op ) ) {
+ if ( BER_BVISNULL( &ndn ) && li->li_idassert_authz == NULL ) {
+ if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
+ rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
+ send_ldap_result( op, rs );
+ LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
+
+ } else {
+ rs->sr_err = LDAP_SUCCESS;
+ binddn = slap_empty_bv;
+ bindcred = slap_empty_bv;
+ break;
+ }
+
+ goto done;
+
+ } else if ( li->li_idassert_authz && !be_isroot( op ) ) {
struct berval authcDN;
if ( BER_BVISNULL( &ndn ) ) {