]> git.sur5r.net Git - openldap/commitdiff
line up with HEAD (ready for release)
authorPierangelo Masarati <ando@openldap.org>
Sat, 13 Jan 2007 12:19:06 +0000 (12:19 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 13 Jan 2007 12:19:06 +0000 (12:19 +0000)
22 files changed:
include/ldap_queue.h
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/compare.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/delete.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/modrdn.c
servers/slapd/back-ldap/proto-ldap.h
servers/slapd/back-ldap/search.c
servers/slapd/back-meta/add.c
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/delete.c
servers/slapd/back-meta/init.c
servers/slapd/back-meta/modify.c
servers/slapd/back-meta/modrdn.c
servers/slapd/back-meta/search.c

index 11ca025ddce5e270a54aa09625c92609c049cdde..b880cc3a98d164cd3deb2ca8c3aad2b7e35d4686 100644 (file)
  * _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);                              \
index b5e07df05cab64163cd7d5303f8592f340a929c0..8625ae8c233f8446a278d0920a966f8267226c27 100644 (file)
@@ -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",
index d4442655eea3593080d23b56f3447127d4049b1d..c248e71e1b6adf29509dd20d53bacc1a8f4e97d8 100644 (file)
@@ -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)
 
index 10a562f5abe768d278a1e6c41af0cbb409419f3f..b4f4529887a667dfa3410c5f97857f92d89e0b0c 100644 (file)
@@ -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 ) {
index ee964a1183d731f38a5965455a0c021e061311dd..a0a1b598075ffc0c58a399431916519a1169884b 100644 (file)
@@ -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;
index 9fd2f1490ee5cec44b213cbf7418448c963473a1..3f68a3294d4da9f1f2fd5a0f04f572d1950fa608 100644 (file)
@@ -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 {
index abf56c37f225fddfd36b2b5908c3820d3aff4ab7..fa6ff873ac472c2e8d711d735512fa0794ee2daf 100644 (file)
@@ -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;
index 8ffb5919858e4b3745871a0e2a5717f59b80ad08..c17cb5b7a25177be136ce3f640c26495215ecf8e 100644 (file)
@@ -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;
index fc8b53d04a966958391301cb29a7fa61c87fc40f..695ce620449bd4bb10d0656dd0a1ff2d2edd215a 100644 (file)
@@ -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;
index 802701d622e74496030ed30cce73954887a9c09e..a578dd19ab02ae6540967243df578faace94caa6 100644 (file)
@@ -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;
index 3d2f8721d1c9deae12b11b0476bdbf836dd095f3..69467ed7ea247112e023be12b5df09165e743ea0 100644 (file)
@@ -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,
index b27d39795ce35b3a2fa6655dd39ac024a8105e1f..75bceebbf8f1c9a0008746f305869379038f4608 100644 (file)
@@ -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;
index a8096eff84f52d2a39b1f79ca462bf3a5271d18e..ef20fdce6c2e99856eaa81508407471a0986d2a8 100644 (file)
@@ -204,7 +204,7 @@ cleanup:;
 
 done:;
        if ( mc ) {
-               meta_back_release_conn( op, mc );
+               meta_back_release_conn( mi, mc );
        }
 
        return rs->sr_err;
index 4bdc0c7635e502b949447053483102c611e571de..4841e1e69fa28230c21696abb080c30ce6ad3bb1 100644 (file)
@@ -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(
index 1ad8ba922d464a76d3924b6441b41325c446fbdc..219bef4442db59ae50b1664daaf3fab498f2528a 100644 (file)
@@ -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 ) {
index 7cef5c040cb210ef444cb8da38d02d9cae64580b..0a8cf10e6bf7803ac194220ba7cfb4a2d3f74e02 100644 (file)
@@ -147,7 +147,7 @@ cleanup:;
        }
 
        if ( mc ) {
-               meta_back_release_conn( op, mc );
+               meta_back_release_conn( mi, mc );
        }
 
        return rs->sr_err;
index a4465ba706c80771b7b1b2143c04b7e4c0f7500e..68635053e2f16154465d38bc86962ba4b4f35277 100644 (file)
@@ -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 );
index 883fac495ca6c008905ac684312afc778913c259..8f1eaac21b794ae66fa905441342b7ceea9cc7ae 100644 (file)
@@ -96,7 +96,7 @@ cleanup:;
        }
        
        if ( mc ) {
-               meta_back_release_conn( op, mc );
+               meta_back_release_conn( mi, mc );
        }
 
        return rs->sr_err;
index 13d59f8a7343bfb82480af48dde9186186ceaa2a..15c64d596c73b6b43087b09e1cf66300a7215497 100644 (file)
@@ -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;
 }
 
index 40d67b53685e232b5d1fbe60c9e541c5a54c8ba1..3ca7cf821f8c8a183f63b72152107e265ddaee0a 100644 (file)
@@ -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;
index 604257cc9d0315fe442bbdd7bf603365ba1012bf..2a14b272085af0f9aaad7ec76bd6491871357d3d 100644 (file)
@@ -158,7 +158,7 @@ cleanup:;
        }
 
        if ( mc ) {
-               meta_back_release_conn( op, mc );
+               meta_back_release_conn( mi, mc );
        }
 
        return rs->sr_err;
index 0e9e04318f2e6bcea198ad0f42c8e4ff14488346..184d798ef8d9b3907d24ca36ad29be3a10407713 100644 (file)
@@ -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;