From: Pierangelo Masarati Date: Sat, 13 Jan 2007 12:19:06 +0000 (+0000) Subject: line up with HEAD (ready for release) X-Git-Tag: OPENLDAP_REL_ENG_2_3_33~5 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d67a30c686607e8e7c24fb6b80f3c14bb946a4ae;p=openldap line up with HEAD (ready for release) --- diff --git a/include/ldap_queue.h b/include/ldap_queue.h index 11ca025ddc..b880cc3a98 100644 --- a/include/ldap_queue.h +++ b/include/ldap_queue.h @@ -111,6 +111,7 @@ * _HEAD + + + + + * _ENTRY + + + + + * _INIT + + + + + + * _ENTRY_INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + @@ -160,6 +161,10 @@ struct { \ (head)->slh_first = NULL; \ } +#define LDAP_SLIST_ENTRY_INIT(var, field) { \ + (var)->field.sle_next = NULL; \ +} + #define LDAP_SLIST_INSERT_AFTER(slistelm, elm, field) do { \ (elm)->field.sle_next = (slistelm)->field.sle_next; \ (slistelm)->field.sle_next = (elm); \ @@ -219,6 +224,10 @@ struct { \ (head)->stqh_last = &(head)->stqh_first; \ } while (0) +#define LDAP_STAILQ_ENTRY_INIT(var, field) { \ + (entry)->field.stqe_next = NULL; \ +} + #define LDAP_STAILQ_FIRST(head) ((head)->stqh_first) #define LDAP_STAILQ_LAST(head, type, field) \ @@ -310,6 +319,11 @@ struct { \ (head)->lh_first = NULL; \ } while (0) +#define LDAP_LIST_ENTRY_INIT(var, field) do { \ + (var)->field.le_next = NULL; \ + (var)->field.le_prev = NULL; \ +} while (0) + #define LDAP_LIST_INSERT_AFTER(listelm, elm, field) do { \ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ (listelm)->field.le_next->field.le_prev = \ @@ -396,6 +410,11 @@ struct { \ (head)->tqh_last = &(head)->tqh_first; \ } while (0) +#define LDAP_TAILQ_ENTRY_INIT(var, field) do { \ + (var)->field.tqe_next = NULL; \ + (var)->field.tqe_prev = NULL; \ +} while (0) + #define LDAP_TAILQ_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ (head)->tqh_first->field.tqe_prev = \ @@ -476,6 +495,11 @@ struct { \ (head)->cqh_last = (void *)(head); \ } while (0) +#define LDAP_CIRCLEQ_ENTRY_INIT(var, field) do { \ + (var)->field.cqe_next = NULL; \ + (var)->field.cqe_prev = NULL; \ +} while (0) + #define LDAP_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ (elm)->field.cqe_next = (listelm)->field.cqe_next; \ (elm)->field.cqe_prev = (listelm); \ diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index b5e07df05c..8625ae8c23 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -125,7 +125,7 @@ cleanup: } if ( lc ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } Debug( LDAP_DEBUG_ARGS, "<== ldap_back_add(\"%s\"): %d\n", diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index d4442655ee..c248e71e1b 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -111,8 +111,9 @@ typedef struct ldapconn_t { #define LDAP_BACK_FCONN_ISTLS (0x00000008U) #define LDAP_BACK_FCONN_BINDING (0x00000010U) #define LDAP_BACK_FCONN_TAINTED (0x00000020U) -#define LDAP_BACK_FCONN_ISIDASR (0x00000040U) -#define LDAP_BACK_FCONN_CACHED (0x00000080U) +#define LDAP_BACK_FCONN_ABANDON (0x00000040U) +#define LDAP_BACK_FCONN_ISIDASR (0x00000080U) +#define LDAP_BACK_FCONN_CACHED (0x00000100U) #define LDAP_BACK_CONN_ISBOUND(lc) LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISBOUND) #define LDAP_BACK_CONN_ISBOUND_SET(lc) LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISBOUND) @@ -136,6 +137,9 @@ typedef struct ldapconn_t { #define LDAP_BACK_CONN_TAINTED(lc) LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_TAINTED) #define LDAP_BACK_CONN_TAINTED_SET(lc) LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_TAINTED) #define LDAP_BACK_CONN_TAINTED_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_TAINTED) +#define LDAP_BACK_CONN_ABANDON(lc) LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ABANDON) +#define LDAP_BACK_CONN_ABANDON_SET(lc) LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ABANDON) +#define LDAP_BACK_CONN_ABANDON_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_ABANDON) #define LDAP_BACK_CONN_ISIDASSERT(lc) LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISIDASR) #define LDAP_BACK_CONN_ISIDASSERT_SET(lc) LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISIDASR) #define LDAP_BACK_CONN_ISIDASSERT_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_ISIDASR) @@ -145,7 +149,6 @@ typedef struct ldapconn_t { #define LDAP_BACK_CONN_CACHED_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_CACHED) unsigned lc_refcnt; - unsigned lc_binding; unsigned lc_flags; time_t lc_create_time; time_t lc_time; @@ -259,27 +262,29 @@ typedef struct ldapinfo_t { #define LDAP_BACK_F_USE_TLS (0x00000002U) #define LDAP_BACK_F_PROPAGATE_TLS (0x00000004U) #define LDAP_BACK_F_TLS_CRITICAL (0x00000008U) +#define LDAP_BACK_F_TLS_LDAPS (0x00000010U) + #define LDAP_BACK_F_TLS_USE_MASK (LDAP_BACK_F_USE_TLS|LDAP_BACK_F_TLS_CRITICAL) #define LDAP_BACK_F_TLS_PROPAGATE_MASK (LDAP_BACK_F_PROPAGATE_TLS|LDAP_BACK_F_TLS_CRITICAL) -#define LDAP_BACK_F_TLS_MASK (LDAP_BACK_F_TLS_USE_MASK|LDAP_BACK_F_TLS_PROPAGATE_MASK) -#define LDAP_BACK_F_CHASE_REFERRALS (0x00000010U) -#define LDAP_BACK_F_PROXY_WHOAMI (0x00000020U) +#define LDAP_BACK_F_TLS_MASK (LDAP_BACK_F_TLS_USE_MASK|LDAP_BACK_F_TLS_PROPAGATE_MASK|LDAP_BACK_F_TLS_LDAPS) +#define LDAP_BACK_F_CHASE_REFERRALS (0x00000020U) +#define LDAP_BACK_F_PROXY_WHOAMI (0x00000040U) -#define LDAP_BACK_F_T_F (0x00000040U) -#define LDAP_BACK_F_T_F_DISCOVER (0x00000080U) +#define LDAP_BACK_F_T_F (0x00000080U) +#define LDAP_BACK_F_T_F_DISCOVER (0x00000100U) #define LDAP_BACK_F_T_F_MASK (LDAP_BACK_F_T_F) #define LDAP_BACK_F_T_F_MASK2 (LDAP_BACK_F_T_F_MASK|LDAP_BACK_F_T_F_DISCOVER) -#define LDAP_BACK_F_MONITOR (0x00000100U) -#define LDAP_BACK_F_SINGLECONN (0x00000200U) -#define LDAP_BACK_F_USE_TEMPORARIES (0x00000400U) +#define LDAP_BACK_F_MONITOR (0x00000200U) +#define LDAP_BACK_F_SINGLECONN (0x00000400U) +#define LDAP_BACK_F_USE_TEMPORARIES (0x00000800U) -#define LDAP_BACK_F_ISOPEN (0x00000800U) +#define LDAP_BACK_F_ISOPEN (0x00001000U) #define LDAP_BACK_F_CANCEL_ABANDON (0x00000000U) -#define LDAP_BACK_F_CANCEL_IGNORE (0x00001000U) -#define LDAP_BACK_F_CANCEL_EXOP (0x00002000U) -#define LDAP_BACK_F_CANCEL_EXOP_DISCOVER (0x00004000U) +#define LDAP_BACK_F_CANCEL_IGNORE (0x00002000U) +#define LDAP_BACK_F_CANCEL_EXOP (0x00004000U) +#define LDAP_BACK_F_CANCEL_EXOP_DISCOVER (0x00008000U) #define LDAP_BACK_F_CANCEL_MASK (LDAP_BACK_F_CANCEL_IGNORE|LDAP_BACK_F_CANCEL_EXOP) #define LDAP_BACK_F_CANCEL_MASK2 (LDAP_BACK_F_CANCEL_MASK|LDAP_BACK_F_CANCEL_EXOP_DISCOVER) diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 10a562f5ab..b4f4529887 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -112,7 +112,7 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg ) #endif /* LDAP_BACK_PRINT_CONNTREE */ static int -ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock ); +ldap_back_freeconn( ldapinfo_t *li, ldapconn_t *lc, int dolock ); static ldapconn_t * ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok, @@ -127,12 +127,46 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok, struct berval *binddn, struct berval *bindcred ); static int -ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, +ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); static int ldap_back_conndnlc_cmp( const void *c1, const void *c2 ); +ldapconn_t * +ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc ) +{ + if ( LDAP_BACK_PCONN_ISPRIV( lc ) ) { + if ( LDAP_BACK_CONN_CACHED( lc ) ) { + assert( lc->lc_q.tqe_prev != NULL ); + assert( li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num > 0 ); + li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num--; + LDAP_TAILQ_REMOVE( &li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_priv, lc, lc_q ); + LDAP_TAILQ_ENTRY_INIT( lc, lc_q ); + LDAP_BACK_CONN_CACHED_CLEAR( lc ); + + } else { + assert( LDAP_BACK_CONN_TAINTED( lc ) ); + assert( lc->lc_q.tqe_prev == NULL ); + } + + } else { + ldapconn_t *tmplc = NULL; + + if ( LDAP_BACK_CONN_CACHED( lc ) ) { + assert( !LDAP_BACK_CONN_TAINTED( lc ) ); + tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, + ldap_back_conndnlc_cmp ); + assert( tmplc == lc ); + LDAP_BACK_CONN_CACHED_CLEAR( lc ); + } + + assert( LDAP_BACK_CONN_TAINTED( lc ) || tmplc == lc ); + } + + return lc; +} + int ldap_back_bind( Operation *op, SlapReply *rs ) { @@ -187,9 +221,7 @@ retry:; * connection with identity assertion */ /* NOTE: use with care */ if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { - assert( lc->lc_binding == 1 ); - lc->lc_binding = 0; - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); return( rc ); } @@ -212,9 +244,6 @@ retry:; } } - assert( lc->lc_binding == 1 ); - lc->lc_binding = 0; - /* must re-insert if local DN changed as result of bind */ if ( !LDAP_BACK_CONN_ISBOUND( lc ) || ( !dn_match( &op->o_req_ndn, &lc->lc_local_ndn ) @@ -237,27 +266,7 @@ retry_lock:; #endif /* LDAP_BACK_PRINT_CONNTREE */ assert( lc->lc_refcnt == 1 ); - if ( LDAP_BACK_PCONN_ISPRIV( lc ) ) { - /* this can happen, for example, if the bind fails - * for some reason... */ - if ( lc->lc_q.tqe_prev != NULL ) { - assert( LDAP_BACK_CONN_CACHED( lc ) ); - assert( li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num > 0 ); - LDAP_TAILQ_REMOVE( &li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_priv, lc, lc_q ); - li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num--; - lc->lc_q.tqe_prev = NULL; - lc->lc_q.tqe_next = NULL; - - } else { - assert( !LDAP_BACK_CONN_CACHED( lc ) ); - } - - } else { - tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, - ldap_back_conndnlc_cmp ); - assert( ( LDAP_BACK_CONN_TAINTED( lc ) && tmplc == NULL ) || lc == tmplc ); - } - LDAP_BACK_CONN_CACHED_CLEAR( lc ); + ldap_back_conn_delete( li, lc ); /* delete all cached connections with the current connection */ if ( LDAP_BACK_SINGLECONN( li ) ) { @@ -312,7 +321,7 @@ retry_lock:; } if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return( rc ); @@ -414,10 +423,8 @@ ldap_back_conndn_dup( void *c1, void *c2 ) } static int -ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock ) +ldap_back_freeconn( ldapinfo_t *li, ldapconn_t *lc, int dolock ) { - ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; - if ( dolock ) { ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); } @@ -426,31 +433,7 @@ ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock ) ldap_back_print_conntree( li, ">>> ldap_back_freeconn" ); #endif /* LDAP_BACK_PRINT_CONNTREE */ - if ( LDAP_BACK_PCONN_ISPRIV( lc ) ) { - if ( lc->lc_q.tqe_prev != NULL ) { - assert( LDAP_BACK_CONN_CACHED( lc ) ); - assert( li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num > 0 ); - li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num--; - LDAP_TAILQ_REMOVE( &li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_priv, lc, lc_q ); - LDAP_BACK_CONN_CACHED_CLEAR( lc ); - - } else { - assert( !LDAP_BACK_CONN_CACHED( lc ) ); - } - lc->lc_q.tqe_prev = NULL; - lc->lc_q.tqe_next = NULL; - - } else { - ldapconn_t *tmplc = NULL; - - if ( LDAP_BACK_CONN_CACHED( lc ) ) { - tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, - ldap_back_conndnlc_cmp ); - assert( tmplc == lc ); - LDAP_BACK_CONN_CACHED_CLEAR( lc ); - } - assert( LDAP_BACK_CONN_TAINTED( lc ) || tmplc == lc ); - } + (void)ldap_back_conn_delete( li, lc ); if ( lc->lc_refcnt == 0 ) { ldap_back_conn_free( (void *)lc ); @@ -610,7 +593,7 @@ retry:; #endif /* HAVE_TLS */ static int -ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) +ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; int version; @@ -620,8 +603,6 @@ ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_bac time_t lc_time = (time_t)(-1); #endif /* HAVE_TLS */ - assert( lcp != NULL ); - ldap_pvt_thread_mutex_lock( &li->li_uri_mutex ); rs->sr_err = ldap_initialize( &ld, li->li_uri ); ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex ); @@ -671,21 +652,16 @@ ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_bac } #endif /* HAVE_TLS */ - if ( *lcp == NULL ) { - *lcp = (ldapconn_t *)ch_calloc( 1, sizeof( ldapconn_t ) ); - (*lcp)->lc_flags = li->li_flags; - } - (*lcp)->lc_ld = ld; - (*lcp)->lc_refcnt = 1; - (*lcp)->lc_binding = 1; + lc->lc_ld = ld; + lc->lc_refcnt = 1; #ifdef HAVE_TLS if ( is_tls ) { - LDAP_BACK_CONN_ISTLS_SET( *lcp ); + LDAP_BACK_CONN_ISTLS_SET( lc ); } else { - LDAP_BACK_CONN_ISTLS_CLEAR( *lcp ); + LDAP_BACK_CONN_ISTLS_CLEAR( lc ); } if ( lc_time != (time_t)(-1) ) { - (*lcp)->lc_time = lc_time; + lc->lc_time = lc_time; } #endif /* HAVE_TLS */ @@ -702,7 +678,7 @@ error_return:; } else { if ( li->li_conn_ttl > 0 ) { - (*lcp)->lc_create_time = op->o_time; + lc->lc_create_time = op->o_time; } } @@ -721,7 +697,6 @@ ldap_back_getconn( ldapconn_t *lc = NULL, lc_curr = { 0 }; int refcnt = 1, - binding = 1, lookupconn = !( sendok & LDAP_BACK_BINDING ); /* if the server is quarantined, and @@ -841,8 +816,7 @@ retry_lock: { LDAP_TAILQ_REMOVE( &li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_priv, lc, lc_q ); - lc->lc_q.tqe_prev = NULL; - lc->lc_q.tqe_next = NULL; + LDAP_TAILQ_ENTRY_INIT( lc, lc_q ); LDAP_TAILQ_INSERT_TAIL( &li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_priv, lc, lc_q ); } @@ -880,7 +854,6 @@ retry_lock: } refcnt = ++lc->lc_refcnt; - binding = ++lc->lc_binding; } } ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); @@ -888,7 +861,11 @@ retry_lock: /* 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 ) { + lc = (ldapconn_t *)ch_calloc( 1, sizeof( ldapconn_t ) ); + lc->lc_flags = li->li_flags; + lc->lc_lcflags = lc_curr.lc_lcflags; + if ( ldap_back_prepare_conn( lc, op, rs, sendok ) != LDAP_SUCCESS ) { + ch_free( lc ); return NULL; } @@ -962,7 +939,6 @@ retry_lock: if ( tmplc != NULL ) { refcnt = ++tmplc->lc_refcnt; - binding = ++tmplc->lc_binding; ldap_back_conn_free( lc ); lc = tmplc; } @@ -980,7 +956,6 @@ retry_lock: LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); assert( lc->lc_refcnt == 1 ); - assert( lc->lc_binding == 1 ); #if LDAP_BACK_PRINT_CONNTREE > 0 ldap_back_print_conntree( li, ">>> ldap_back_getconn(insert)" ); @@ -1013,8 +988,8 @@ retry_lock: char buf[ SLAP_TEXT_BUFLEN ]; snprintf( buf, sizeof( buf ), - "lc=%p inserted refcnt=%u binding=%u rc=%d", - (void *)lc, refcnt, binding, rs->sr_err ); + "lc=%p inserted refcnt=%u rc=%d", + (void *)lc, refcnt, rs->sr_err ); Debug( LDAP_DEBUG_TRACE, "=>ldap_back_getconn: %s: %s\n", @@ -1069,26 +1044,8 @@ retry_lock: ldap_back_print_conntree( li, ">>> ldap_back_getconn(timeout)" ); #endif /* LDAP_BACK_PRINT_CONNTREE */ - if ( LDAP_BACK_PCONN_ISPRIV( lc ) ) { - if ( lc->lc_q.tqe_prev != NULL ) { - assert( LDAP_BACK_CONN_CACHED( lc ) ); - assert( li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num > 0 ); - LDAP_TAILQ_REMOVE( &li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_priv, - lc, lc_q ); - li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num--; - lc->lc_q.tqe_prev = NULL; - lc->lc_q.tqe_next = NULL; - - } else { - assert( !LDAP_BACK_CONN_CACHED( lc ) ); - } - - } else { - (void)avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, - ldap_back_conndnlc_cmp ); - } + (void)ldap_back_conn_delete( li, lc ); LDAP_BACK_CONN_TAINTED_SET( lc ); - LDAP_BACK_CONN_CACHED_CLEAR( lc ); #if LDAP_BACK_PRINT_CONNTREE > 0 ldap_back_print_conntree( li, "<<< ldap_back_getconn(timeout)" ); @@ -1101,8 +1058,9 @@ retry_lock: char buf[ SLAP_TEXT_BUFLEN ]; snprintf( buf, sizeof( buf ), - "conn %p fetched refcnt=%u binding=%u%s", - (void *)lc, refcnt, binding, expiring ? " expiring" : "" ); + "conn %p fetched refcnt=%u%s", + (void *)lc, refcnt, + expiring ? " expiring" : "" ); Debug( LDAP_DEBUG_TRACE, "=>ldap_back_getconn: %s.\n", buf, 0, 0 ); } @@ -1117,12 +1075,10 @@ done:; void ldap_back_release_conn_lock( - Operation *op, - SlapReply *rs, + ldapinfo_t *li, ldapconn_t **lcp, int dolock ) { - ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; ldapconn_t *lc = *lcp; @@ -1133,7 +1089,7 @@ ldap_back_release_conn_lock( LDAP_BACK_CONN_BINDING_CLEAR( lc ); lc->lc_refcnt--; if ( LDAP_BACK_CONN_TAINTED( lc ) ) { - ldap_back_freeconn( op, lc, 0 ); + ldap_back_freeconn( li, lc, 0 ); *lcp = NULL; } if ( dolock ) { @@ -1264,7 +1220,6 @@ retry_lock:; /* check if already bound */ rc = isbound = LDAP_BACK_CONN_ISBOUND( lc ); if ( isbound ) { - lc->lc_binding--; if ( dolock ) { ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); } @@ -1286,16 +1241,6 @@ retry_lock:; } } - /* wait for pending operations to finish */ - /* FIXME: may become a bottleneck! */ - if ( lc->lc_refcnt != lc->lc_binding ) { - if ( dolock ) { - ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); - } - ldap_pvt_thread_yield(); - goto retry_lock; - } - if ( dolock ) { ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); } @@ -1403,9 +1348,8 @@ retry:; lc->lc_ld = NULL; /* lc here must be the regular lc, reset and ready for init */ - rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok ); + rs->sr_err = ldap_back_prepare_conn( lc, op, rs, sendok ); if ( rs->sr_err != LDAP_SUCCESS ) { - lc->lc_binding--; lc->lc_refcnt = 0; } } @@ -1420,22 +1364,11 @@ retry:; } goto retry; } - - } else { - if ( dolock ) { - ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); - } - lc->lc_binding--; - if ( dolock ) { - ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); - } } - /* FIXME: one binding-- too many? */ - lc->lc_binding--; assert( lc->lc_refcnt == 1 ); lc->lc_refcnt = 0; - ldap_back_freeconn( op, lc, dolock ); + ldap_back_freeconn( li, lc, dolock ); *lcp = NULL; rs->sr_err = slap_map_api2result( rs ); @@ -1459,11 +1392,10 @@ retry:; } done:; - lc->lc_binding--; LDAP_BACK_CONN_BINDING_CLEAR( lc ); rc = LDAP_BACK_CONN_ISBOUND( lc ); if ( !rc ) { - ldap_back_release_conn_lock( op, rs, lcp, dolock ); + ldap_back_release_conn_lock( li, lcp, dolock ); } else if ( LDAP_BACK_SAVECRED( li ) ) { ldap_set_rebind_proc( lc->lc_ld, li->li_rebind_f, lc ); @@ -1773,11 +1705,11 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_ LDAP_BACK_CONN_ISBOUND_CLEAR( (*lcp) ); /* lc here must be the regular lc, reset and ready for init */ - rc = ldap_back_prepare_conn( lcp, op, rs, sendok ); + rc = ldap_back_prepare_conn( *lcp, op, rs, sendok ); if ( rc != LDAP_SUCCESS ) { /* freeit, because lc_refcnt == 1 */ (*lcp)->lc_refcnt = 0; - (void)ldap_back_freeconn( op, *lcp, 0 ); + (void)ldap_back_freeconn( li, *lcp, 0 ); *lcp = NULL; rc = 0; @@ -1793,7 +1725,7 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_ /* freeit, because lc_refcnt == 1 */ (*lcp)->lc_refcnt = 0; LDAP_BACK_CONN_TAINTED_SET( *lcp ); - (void)ldap_back_freeconn( op, *lcp, 0 ); + (void)ldap_back_freeconn( li, *lcp, 0 ); *lcp = NULL; } } @@ -1804,7 +1736,7 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_ (void *)(*lcp), (*lcp)->lc_refcnt, 0 ); LDAP_BACK_CONN_TAINTED_SET( *lcp ); - ldap_back_release_conn_lock( op, rs, lcp, 0 ); + ldap_back_release_conn_lock( li, lcp, 0 ); assert( *lcp == NULL ); if ( sendok ) { diff --git a/servers/slapd/back-ldap/compare.c b/servers/slapd/back-ldap/compare.c index ee964a1183..a0a1b59807 100644 --- a/servers/slapd/back-ldap/compare.c +++ b/servers/slapd/back-ldap/compare.c @@ -78,7 +78,7 @@ cleanup: (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls ); if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rs->sr_err; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 9fd2f1490e..3f68a3294d 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -551,7 +551,6 @@ slap_idassert_authzfrom_parse( ConfigArgs *c, slap_idassert_t *si ) struct berval bv; if ( strcmp( c->argv[ 1 ], "*" ) == 0 - || strcmp( c->argv[ 1 ], ".*" ) == 0 || strcmp( c->argv[ 1 ], "dn:*" ) == 0 || strcasecmp( c->argv[ 1 ], "dn.regex:.*" ) == 0 ) { @@ -1979,7 +1978,7 @@ retry: } if ( lc != NULL ) { - ldap_back_release_conn( &op2, rs, lc ); + ldap_back_release_conn( (ldapinfo_t *)op2.o_bd->be_private, lc ); } } else { diff --git a/servers/slapd/back-ldap/delete.c b/servers/slapd/back-ldap/delete.c index abf56c37f2..fa6ff873ac 100644 --- a/servers/slapd/back-ldap/delete.c +++ b/servers/slapd/back-ldap/delete.c @@ -36,7 +36,7 @@ ldap_back_delete( Operation *op, SlapReply *rs ) { - ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; ldapconn_t *lc = NULL; ber_int_t msgid; @@ -76,7 +76,7 @@ cleanup: (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls ); if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rc; diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index 8ffb591985..c17cb5b7a2 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -78,7 +78,7 @@ ldap_back_extended_one( Operation *op, SlapReply *rs, BI_op_extended exop ) done:; if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rc; @@ -226,7 +226,7 @@ retry: } if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rc; @@ -336,7 +336,7 @@ retry: } if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rc; diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index fc8b53d04a..695ce62044 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -130,7 +130,7 @@ cleanup:; ch_free( modv ); if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rc; diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c index 802701d622..a578dd19ab 100644 --- a/servers/slapd/back-ldap/modrdn.c +++ b/servers/slapd/back-ldap/modrdn.c @@ -101,7 +101,7 @@ cleanup: (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls ); if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rc; diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index 3d2f8721d1..69467ed7ea 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -47,8 +47,8 @@ extern BI_connection_destroy ldap_back_conn_destroy; extern BI_entry_get_rw ldap_back_entry_get; -void ldap_back_release_conn_lock( Operation *op, SlapReply *rs, ldapconn_t **lcp, int dolock ); -#define ldap_back_release_conn(op, rs, lc) ldap_back_release_conn_lock((op), (rs), &(lc), 1) +void ldap_back_release_conn_lock( ldapinfo_t *li, ldapconn_t **lcp, int dolock ); +#define ldap_back_release_conn(li, lc) ldap_back_release_conn_lock((li), &(lc), 1) int ldap_back_dobind( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); int ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); int ldap_back_map_result( SlapReply *rs ); @@ -63,6 +63,8 @@ extern int ldap_back_conn_cmp( const void *c1, const void *c2); extern int ldap_back_conndn_dup( void *c1, void *c2 ); extern void ldap_back_conn_free( void *c ); +extern ldapconn_t * ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc ); + extern int ldap_back_proxy_authz_ctrl( struct berval *bound_ndn, diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index b27d39795c..75bceebbf8 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -264,7 +264,7 @@ retry: for ( rc = 0; rc != -1; rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ONE, &tv, &res ) ) { /* check for abandon */ - if ( op->o_abandon ) { + if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( lc ) ) { if ( rc > 0 ) { ldap_msgfree( res ); } @@ -535,7 +535,7 @@ finish:; } if ( lc != NULL ) { - ldap_back_release_conn( op, rs, lc ); + ldap_back_release_conn( li, lc ); } return rs->sr_err; @@ -822,7 +822,7 @@ retry: rc = ldap_build_entry( op, e, *ent, &bdn ); if ( rc != LDAP_SUCCESS ) { - ch_free( *ent ); + entry_free( *ent ); *ent = NULL; } @@ -838,7 +838,7 @@ cleanup: } if ( lc != NULL ) { - ldap_back_release_conn( op, &rs, lc ); + ldap_back_release_conn( li, lc ); } return rc; diff --git a/servers/slapd/back-meta/add.c b/servers/slapd/back-meta/add.c index a8096eff84..ef20fdce6c 100644 --- a/servers/slapd/back-meta/add.c +++ b/servers/slapd/back-meta/add.c @@ -204,7 +204,7 @@ cleanup:; done:; if ( mc ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return rs->sr_err; diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 4bdc0c7635..4841e1e69f 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -194,6 +194,7 @@ struct metainfo_t; #define META_NOT_CANDIDATE ((ber_tag_t)0x0) #define META_CANDIDATE ((ber_tag_t)0x1) #define META_BINDING ((ber_tag_t)0x2) +#define META_RETRYING ((ber_tag_t)0x4) typedef struct metasingleconn_t { #define META_CND_ISSET(rs,f) ( ( (rs)->sr_tag & (f) ) == (f) ) @@ -207,6 +208,9 @@ typedef struct metasingleconn_t { #define META_IS_BINDING(rs) META_CND_ISSET( (rs), META_BINDING ) #define META_BINDING_SET(rs) META_CND_SET( (rs), META_BINDING ) #define META_BINDING_CLEAR(rs) META_CND_CLEAR( (rs), META_BINDING ) +#define META_IS_RETRYING(rs) META_CND_ISSET( (rs), META_RETRYING ) +#define META_RETRYING_SET(rs) META_CND_SET( (rs), META_RETRYING ) +#define META_RETRYING_CLEAR(rs) META_CND_CLEAR( (rs), META_RETRYING ) LDAP *msc_ld; time_t msc_time; @@ -369,14 +373,18 @@ typedef struct metainfo_t { #define META_BACK_F_ONERR_REPORT (0x00200000U) #define META_BACK_F_ONERR_MASK (META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT) #define META_BACK_F_DEFER_ROOTDN_BIND (0x00400000U) -#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U) +#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U) /* users always proxyauthz */ +#define META_BACK_F_PROXYAUTHZ_ANON (0x01000000U) /* anonymous always proxyauthz */ +#define META_BACK_F_PROXYAUTHZ_NOANON (0x02000000U) /* anonymous remains anonymous */ -#define META_BACK_ONERR_STOP(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_STOP ) -#define META_BACK_ONERR_REPORT(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_REPORT ) -#define META_BACK_ONERR_CONTINUE(mi) ( !( (mi)->mi_flags & META_BACK_F_ONERR_MASK ) ) +#define META_BACK_ONERR_STOP(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_STOP ) +#define META_BACK_ONERR_REPORT(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_REPORT ) +#define META_BACK_ONERR_CONTINUE(mi) ( !LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_MASK ) ) -#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND ) -#define META_BACK_PROXYAUTHZ_ALWAYS(mi) ( (mi)->mi_flags & META_BACK_F_PROXYAUTHZ_ALWAYS ) +#define META_BACK_DEFER_ROOTDN_BIND(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_DEFER_ROOTDN_BIND ) +#define META_BACK_PROXYAUTHZ_ALWAYS(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ALWAYS ) +#define META_BACK_PROXYAUTHZ_ANON(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ANON ) +#define META_BACK_PROXYAUTHZ_NOANON(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_NOANON ) int mi_version; time_t mi_network_timeout; @@ -404,10 +412,10 @@ meta_back_getconn( extern void meta_back_release_conn_lock( - Operation *op, + metainfo_t *mi, metaconn_t *mc, int dolock ); -#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 1 ) +#define meta_back_release_conn(mi, mc) meta_back_release_conn_lock( (mi), (mc), 1 ) extern int meta_back_retry( diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 1ad8ba922d..219bef4442 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -205,7 +205,9 @@ meta_back_bind( Operation *op, SlapReply *rs ) ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ) ); } - if ( !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) ) { + if ( !LDAP_BACK_PCONN_ISPRIV( mc ) + && !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) ) + { metaconn_t *tmpmc; int lerr; @@ -271,7 +273,7 @@ retry_lock:; } if ( mc != NULL ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } /* @@ -590,7 +592,7 @@ meta_back_single_dobind( LDAP_BACK_CONN_BINDING_CLEAR( msc ); if ( META_BACK_ONERR_STOP( mi ) ) { LDAP_BACK_CONN_TAINTED_SET( mc ); - meta_back_release_conn_lock( op, mc, 0 ); + meta_back_release_conn_lock( mi, mc, 0 ); *mcp = NULL; } if ( dolock ) { @@ -707,7 +709,7 @@ retry_binding:; ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); LDAP_BACK_CONN_BINDING_CLEAR( msc ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return 0; @@ -766,7 +768,7 @@ done:; op->o_log_prefix, LDAP_BACK_PCONN_ID( mc ), bound ); if ( bound == 0 ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); send_err:; if ( sendok & LDAP_BACK_SENDERR ) { @@ -1225,7 +1227,10 @@ meta_back_proxy_authz_cred( default: /* NOTE: rootdn can always idassert */ - if ( BER_BVISNULL( &ndn ) && mt->mt_idassert_authz == NULL ) { + if ( BER_BVISNULL( &ndn ) + && mt->mt_idassert_authz == NULL + && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) + { if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { rs->sr_err = LDAP_INAPPROPRIATE_AUTH; if ( sendok & LDAP_BACK_SENDERR ) { diff --git a/servers/slapd/back-meta/compare.c b/servers/slapd/back-meta/compare.c index 7cef5c040c..0a8cf10e6b 100644 --- a/servers/slapd/back-meta/compare.c +++ b/servers/slapd/back-meta/compare.c @@ -147,7 +147,7 @@ cleanup:; } if ( mc ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return rs->sr_err; diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index a4465ba706..68635053e2 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -734,7 +734,7 @@ meta_back_retry( * let the caller do what's best before * releasing */ if ( META_BACK_ONERR_STOP( mi ) ) { - meta_back_release_conn_lock( op, mc, 0 ); + meta_back_release_conn_lock( mi, mc, 0 ); *mcp = NULL; } else { @@ -750,8 +750,7 @@ meta_back_retry( LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q ); mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--; - mc->mc_q.tqe_prev = NULL; - mc->mc_q.tqe_next = NULL; + LDAP_TAILQ_ENTRY_INIT( mc, mc_q ); } else { assert( !LDAP_BACK_CONN_CACHED( mc ) ); @@ -1017,17 +1016,28 @@ meta_back_getconn( SlapReply *candidates = meta_back_candidates_get( op ); /* Internal searches are privileged and shared. So is root. */ - /* FIXME: there seems to be concurrency issues */ - if ( META_BACK_PROXYAUTHZ_ALWAYS( mi ) || op->o_do_not_cache || be_isroot( op ) ) { - mc_curr.mc_local_ndn = op->o_bd->be_rootndn; + if ( ( !BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ALWAYS( mi ) ) + || ( BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ANON( mi ) ) + || op->o_do_not_cache || be_isroot( op ) ) + { LDAP_BACK_CONN_ISPRIV_SET( &mc_curr ); + mc_curr.mc_local_ndn = op->o_bd->be_rootndn; LDAP_BACK_PCONN_ROOTDN_SET( &mc_curr, op ); + } else if ( BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_NOANON( mi ) ) + { + LDAP_BACK_CONN_ISANON_SET( &mc_curr ); + BER_BVSTR( &mc_curr.mc_local_ndn, "" ); + LDAP_BACK_PCONN_ANON_SET( &mc_curr, op ); + } else { mc_curr.mc_local_ndn = op->o_ndn; /* Explicit binds must not be shared */ - if ( op->o_tag == LDAP_REQ_BIND || SLAP_IS_AUTHZ_BACKEND( op ) ) { + if ( !BER_BVISEMPTY( &op->o_ndn ) + || op->o_tag == LDAP_REQ_BIND + || SLAP_IS_AUTHZ_BACKEND( op ) ) + { mc_curr.mc_conn = op->o_conn; } else { @@ -1037,7 +1047,10 @@ meta_back_getconn( } /* Explicit Bind requests always get their own conn */ - if ( !( sendok & LDAP_BACK_BINDING ) ) { + if ( sendok & LDAP_BACK_BINDING ) { + mc_curr.mc_conn = op->o_conn; + + } else { /* Searches for a metaconn in the avl tree */ retry_lock:; ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); @@ -1058,8 +1071,7 @@ retry_lock:; { LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q ); - mc->mc_q.tqe_prev = NULL; - mc->mc_q.tqe_next = NULL; + LDAP_TAILQ_ENTRY_INIT( mc, mc_q ); LDAP_TAILQ_INSERT_TAIL( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q ); } @@ -1110,8 +1122,7 @@ retry_lock:; LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q ); mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--; - mc->mc_q.tqe_prev = NULL; - mc->mc_q.tqe_next = NULL; + LDAP_TAILQ_ENTRY_INIT( mc, mc_q ); } else { assert( !LDAP_BACK_CONN_CACHED( mc ) ); @@ -1237,7 +1248,7 @@ retry_lock:; meta_back_conn_free( mc ); } else { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } rs->sr_err = LDAP_NO_SUCH_OBJECT; @@ -1288,7 +1299,7 @@ retry_lock:; if ( i < 0 || rs->sr_err != LDAP_SUCCESS ) { if ( mc != NULL ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } if ( sendok & LDAP_BACK_SENDERR ) { @@ -1307,7 +1318,7 @@ retry_lock:; if ( dn_type == META_DNTYPE_NEWPARENT && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i ) { if ( mc != NULL ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } rs->sr_err = LDAP_UNWILLING_TO_PERFORM; @@ -1402,7 +1413,7 @@ retry_lock2:; meta_back_conn_free( mc ); } else { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return NULL; } @@ -1499,7 +1510,7 @@ retry_lock2:; meta_back_conn_free( mc ); } else { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return NULL; @@ -1522,7 +1533,7 @@ retry_lock2:; meta_back_conn_free( mc ); } else { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } if ( rs->sr_err == LDAP_SUCCESS ) { @@ -1647,12 +1658,10 @@ done:; void meta_back_release_conn_lock( - Operation *op, + metainfo_t *mi, metaconn_t *mc, int dolock ) { - metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; - assert( mc != NULL ); if ( dolock ) { @@ -1667,8 +1676,6 @@ meta_back_release_conn_lock( * the connection space (and eat up resources). Maybe this * should be configurable... */ if ( LDAP_BACK_CONN_TAINTED( mc ) ) { - Debug( LDAP_DEBUG_TRACE, "%s meta_back_release_conn: mc=%p conn=%ld tainted.\n", - op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc ) ); #if META_BACK_PRINT_CONNTREE > 0 meta_back_print_conntree( mi, ">>> meta_back_release_conn" ); #endif /* META_BACK_PRINT_CONNTREE */ @@ -1677,14 +1684,13 @@ meta_back_release_conn_lock( if ( mc->mc_q.tqe_prev != NULL ) { assert( LDAP_BACK_CONN_CACHED( mc ) ); assert( mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num > 0 ); - mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--; LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q ); + mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--; + LDAP_TAILQ_ENTRY_INIT( mc, mc_q ); } else { assert( !LDAP_BACK_CONN_CACHED( mc ) ); } - mc->mc_q.tqe_prev = NULL; - mc->mc_q.tqe_next = NULL; } else { metaconn_t *tmpmc; @@ -1692,12 +1698,7 @@ meta_back_release_conn_lock( tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc, meta_back_conndnmc_cmp ); - if ( tmpmc == NULL ) { - Debug( LDAP_DEBUG_TRACE, "%s: meta_back_release_conn: unable to find mc=%p\n", - op->o_log_prefix, (void *)mc, 0 ); - } else { - assert( tmpmc == mc ); - } + assert( tmpmc == NULL && tmpmc == mc ); } LDAP_BACK_CONN_CACHED_CLEAR( mc ); diff --git a/servers/slapd/back-meta/delete.c b/servers/slapd/back-meta/delete.c index 883fac495c..8f1eaac21b 100644 --- a/servers/slapd/back-meta/delete.c +++ b/servers/slapd/back-meta/delete.c @@ -96,7 +96,7 @@ cleanup:; } if ( mc ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return rs->sr_err; diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c index 13d59f8a73..15c64d596c 100644 --- a/servers/slapd/back-meta/init.c +++ b/servers/slapd/back-meta/init.c @@ -119,6 +119,8 @@ meta_back_db_open( int i, not_always = 0, + not_always_anon_proxyauthz = 0, + not_always_anon_non_prescriptive = 0, rc; for ( i = 0; i < mi->mi_ntargets; i++ ) { @@ -144,17 +146,48 @@ meta_back_db_open( if ( not_always == 0 ) { if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) - || !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) + || mt->mt_idassert_authz != NULL ) { not_always = 1; } } + + if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) + && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) ) + { + Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): " + "target #%d inconsistent idassert configuration " + "(likely authz=\"*\" used with \"non-prescriptive\" flag)\n", + be->be_suffix[ 0 ].bv_val, i, 0 ); + return 1; + } + + if ( not_always_anon_proxyauthz == 0 ) { + if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) + { + not_always_anon_proxyauthz = 1; + } + } + + if ( not_always_anon_non_prescriptive == 0 ) { + if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) ) + { + not_always_anon_non_prescriptive = 1; + } + } } if ( not_always == 0 ) { mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS; } + if ( not_always_anon_proxyauthz == 0 ) { + mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON; + + } else if ( not_always_anon_non_prescriptive == 0 ) { + mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON; + } + return 0; } diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index 40d67b5368..3ca7cf821f 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -214,7 +214,7 @@ cleanup:; free( modv ); if ( mc ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return rs->sr_err; diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c index 604257cc9d..2a14b27208 100644 --- a/servers/slapd/back-meta/modrdn.c +++ b/servers/slapd/back-meta/modrdn.c @@ -158,7 +158,7 @@ cleanup:; } if ( mc ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return rs->sr_err; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 0e9e04318f..184d798ef8 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -230,6 +230,7 @@ meta_search_dobind_init( assert( msc->msc_ld != NULL ); +retry:; rc = ldap_sasl_bind( msc->msc_ld, binddn.bv_val, LDAP_SASL_SIMPLE, &cred, NULL, NULL, &candidates[ candidate ].sr_msgid ); @@ -254,9 +255,49 @@ meta_search_dobind_init( down:; /* This is the worst thing that could happen: * the search will wait until the retry is over. */ - if ( meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) { - candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; - return META_SEARCH_CANDIDATE; + if ( !META_IS_RETRYING( &candidates[ candidate ] ) ) { + META_RETRYING_SET( &candidates[ candidate ] ); + + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + + assert( mc->mc_refcnt > 0 ); + if ( StatslogTest( LDAP_DEBUG_ANY ) ) { + char buf[ SLAP_TEXT_BUFLEN ]; + + /* this lock is required; however, + * it's invoked only when logging is on */ + ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex ); + snprintf( buf, sizeof( buf ), + "retrying URI=\"%s\" DN=\"%s\"", + mt->mt_uri, + BER_BVISNULL( &msc->msc_bound_ndn ) ? + "" : msc->msc_bound_ndn.bv_val ); + ldap_pvt_thread_mutex_unlock( &mt->mt_uri_mutex ); + + Debug( LDAP_DEBUG_ANY, + "%s meta_search_dobind_init[%d]: %s.\n", + op->o_log_prefix, candidate, buf ); + } + + meta_clear_one_candidate( op, mc, candidate ); + LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); + + ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn ); + + /* mc here must be the regular mc, reset and ready for init */ + rc = meta_back_init_one_conn( op, rs, mc, candidate, + LDAP_BACK_CONN_ISPRIV( mc ), LDAP_BACK_DONTSEND, 0 ); + + if ( rc == LDAP_SUCCESS ) { + LDAP_BACK_CONN_BINDING_SET( msc ); + } + + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); + + if ( rc == LDAP_SUCCESS ) { + candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; + goto retry; + } } if ( *mcp == NULL ) { @@ -276,7 +317,7 @@ other:; candidates[ candidate ].sr_err = rc; if ( META_BACK_ONERR_STOP( mi ) ) { LDAP_BACK_CONN_TAINTED_SET( mc ); - meta_back_release_conn_lock( op, mc, 0 ); + meta_back_release_conn_lock( mi, mc, 0 ); *mcp = NULL; rs->sr_err = rc; @@ -329,7 +370,7 @@ meta_search_dobind_result( candidates[ candidate ].sr_err = rc; if ( META_BACK_ONERR_STOP( mi ) ) { LDAP_BACK_CONN_TAINTED_SET( mc ); - meta_back_release_conn_lock( op, mc, 0 ); + meta_back_release_conn_lock( mi, mc, 0 ); *mcp = NULL; retcode = META_SEARCH_ERR; rs->sr_err = rc; @@ -725,7 +766,7 @@ getconn:; op->o_log_prefix, (void *)mc, 0 ); #endif /* DEBUG_205 */ - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); mc = NULL; needbind = 0; @@ -907,7 +948,7 @@ getconn:; } /* check for abandon */ - if ( op->o_abandon ) { + if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) { break; } @@ -1353,7 +1394,7 @@ free_message:; } /* check for abandon */ - if ( op->o_abandon || doabandon ) { + if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) { for ( i = 0; i < mi->mi_ntargets; i++ ) { if ( candidates[ i ].sr_msgid >= 0 ) { if ( META_IS_BINDING( &candidates[ i ] ) ) { @@ -1391,9 +1432,10 @@ free_message:; if ( op->o_abandon ) { rc = SLAPD_ABANDON; - /* let send_ldap_result play cleanup handlers (ITS#4645) */ - break; } + + /* let send_ldap_result play cleanup handlers (ITS#4645) */ + break; } /* if no entry was found during this loop, @@ -1410,34 +1452,7 @@ free_message:; lutil_timermul( &save_tv, 2, &save_tv ); } -#if 0 - if ( StatslogTest( LDAP_DEBUG_TRACE ) ) { - char buf[ SLAP_TEXT_BUFLEN ]; - - snprintf( buf, sizeof( buf ), "%s %ld.%06ld %d/%d mc=%p", - op->o_log_prefix, save_tv.tv_sec, save_tv.tv_usec, - ncandidates, initial_candidates, mc ); - Debug( LDAP_DEBUG_TRACE, "### %s\n", buf, 0, 0 ); - for ( i = 0; i < mi->mi_ntargets; i++ ) { - if ( candidates[ i ].sr_msgid == META_MSGID_IGNORE ) { - continue; - } - - snprintf( buf, sizeof( buf ), "[%ld] ld=%p%s%s\n", - i, - mc->mc_conns[ i ].msc_ld, - ( candidates[ i ].sr_msgid == META_MSGID_NEED_BIND ) ? " needbind" : "", - META_IS_BINDING( &candidates[ i ] ) ? " binding" : "" ); - Debug( LDAP_DEBUG_TRACE, "### %s\n", buf, 0, 0 ); - } - } -#endif - if ( alreadybound == 0 ) { -#if 0 - Debug( LDAP_DEBUG_TRACE, "### %s select(%ld.%06ld)\n", - op->o_log_prefix, save_tv.tv_sec, save_tv.tv_usec ); -#endif tv = save_tv; (void)select( 0, NULL, NULL, NULL, &tv ); @@ -1527,28 +1542,6 @@ free_message:; matched = op->o_bd->be_suffix[ 0 ].bv_val; } -#if 0 - { - char buf[ SLAP_TEXT_BUFLEN ]; - char cnd[ SLAP_TEXT_BUFLEN ]; - int i; - - for ( i = 0; i < mi->mi_ntargets; i++ ) { - if ( META_IS_CANDIDATE( &candidates[ i ] ) ) { - cnd[ i ] = '*'; - } else { - cnd[ i ] = ' '; - } - } - cnd[ i ] = '\0'; - - snprintf( buf, sizeof( buf ), "%s meta_back_search: is_scope=%d is_ok=%d cnd=\"%s\"\n", - op->o_log_prefix, initial_candidates, is_ok, cnd ); - - Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 ); - } -#endif - /* * In case we returned at least one entry, we return LDAP_SUCCESS * otherwise, the latter error code we got @@ -1661,7 +1654,7 @@ finish:; } if ( mc ) { - meta_back_release_conn( op, mc ); + meta_back_release_conn( mi, mc ); } return rs->sr_err;