#define LDAP_BACK_F_PROXY_WHOAMI 0x0020U
#define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x0040U
-#define LDAP_BACK_F_SUPPORT_T_F 0x0080U
-#define LDAP_BACK_F_SUPPORT_T_F_MASK (LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER)
+#define LDAP_BACK_F_SUPPORT_T_F 0x0080U
+#define LDAP_BACK_F_SUPPORT_T_F_MASK (LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER)
#define LDAP_BACK_F_MONITOR 0x0100U
+#define LDAP_BACK_F_SINGLECONN 0x0200U
#define LDAP_BACK_ISSET(li,f) ( ( (li)->li_flags & (f) ) == (f) )
#define LDAP_BACK_SAVECRED(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_SAVECRED )
#define LDAP_BACK_CHASE_REFERRALS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_CHASE_REFERRALS )
#define LDAP_BACK_PROXY_WHOAMI(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROXY_WHOAMI )
#define LDAP_BACK_MONITOR(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_MONITOR )
+#define LDAP_BACK_SINGLECONN(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_SINGLECONN )
int li_version;
ldap_back_conndnlc_cmp );
assert( tmplc == NULL || lc == tmplc );
+ /* delete all cached connections with the current connection */
+ if ( LDAP_BACK_SINGLECONN( li ) ) {
+ while ( ( tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ) ) != NULL )
+ {
+ Debug( LDAP_DEBUG_TRACE,
+ "=>ldap_back_bind: destroying conn %ld (refcnt=%u)\n",
+ LDAP_BACK_PCONN_ID( lc->lc_conn ), lc->lc_refcnt, 0 );
+
+ if ( lc->lc_refcnt != 0 ) {
+ /* taint it */
+ LDAP_BACK_CONN_TAINTED_SET( tmplc );
+
+ } else {
+ /*
+ * Needs a test because the handler may be corrupted,
+ * and calling ldap_unbind on a corrupted header results
+ * in a segmentation fault
+ */
+ ldap_back_conn_free( tmplc );
+ }
+ }
+ }
+
if ( LDAP_BACK_CONN_ISBOUND( lc ) ) {
ber_bvreplace( &lc->lc_local_ndn, &op->o_req_ndn );
lerr = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,
LDAP_BACK_CFG_CONN_TTL,
LDAP_BACK_CFG_NETWORK_TIMEOUT,
LDAP_BACK_CFG_VERSION,
+ LDAP_BACK_CFG_SINGLECONN,
LDAP_BACK_CFG_REWRITE,
LDAP_BACK_CFG_LAST
"SYNTAX OMsInteger "
"SINGLE-VALUE )",
NULL, NULL },
+ { "single-conn", "TREU/FALSE", 2, 0, 0,
+ ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN,
+ ldap_back_cf_gen, "( OLcfgDbAt:3.19 "
+ "NAME 'olcDbSingleConn' "
+ "DESC 'cache a single connection per identity' "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )",
+ NULL, NULL },
{ "suffixmassage", "[virtual]> <real", 2, 3, 0,
ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
ldap_back_cf_gen, NULL, NULL, NULL },
"$ olcDbProxyWhoAmI "
"$ olcDbTimeout "
"$ olcDbIdleTimeout "
+ "$ olcDbSingleConn "
") )",
Cft_Database, ldapcfg},
{ NULL, 0, NULL }
c->value_int = li->li_version;
break;
+ case LDAP_BACK_CFG_SINGLECONN:
+ c->value_int = LDAP_BACK_SINGLECONN( li );
+ break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
li->li_version = 0;
break;
+ case LDAP_BACK_CFG_SINGLECONN:
+ li->li_flags &= ~LDAP_BACK_F_SINGLECONN;
+ break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
li->li_version = c->value_int;
break;
+ case LDAP_BACK_CFG_SINGLECONN:
+ if ( c->value_int ) {
+ li->li_flags |= LDAP_BACK_F_SINGLECONN;
+
+ } else {
+ li->li_flags &= ~LDAP_BACK_F_SINGLECONN;
+ }
+ break;
+
case LDAP_BACK_CFG_REWRITE:
snprintf( c->msg, sizeof( c->msg ),
"rewrite/remap capabilities have been moved "