From: Pierangelo Masarati Date: Sun, 14 May 2006 17:32:15 +0000 (+0000) Subject: "single-conn" forces flushing of existing conns during rebind on same conn (ITS#4546) X-Git-Tag: OPENLDAP_REL_ENG_2_4_1ALPHA~2^2~15 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=0c33c17bb517771063339b30cbbdd895e7b60371;p=openldap "single-conn" forces flushing of existing conns during rebind on same conn (ITS#4546) --- diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 49017d2ed2..e8e73cc462 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -188,10 +188,11 @@ typedef struct ldapinfo_t { #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 ) @@ -201,6 +202,7 @@ typedef struct ldapinfo_t { #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; diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 21b49cf007..9ed0cb3e1f 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -129,6 +129,29 @@ retry_lock:; 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, diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 7a61961127..ba22d85120 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -64,6 +64,7 @@ enum { 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 @@ -250,6 +251,14 @@ static ConfigTable ldapcfg[] = { "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]> 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 ); @@ -722,6 +736,10 @@ ldap_back_cf_gen( ConfigArgs *c ) 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 ); @@ -1335,6 +1353,15 @@ done_url:; 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 "