]> git.sur5r.net Git - openldap/commitdiff
import fix to ITS#3217 (cached connections failover) from HEAD
authorPierangelo Masarati <ando@openldap.org>
Fri, 9 Jul 2004 18:32:00 +0000 (18:32 +0000)
committerPierangelo Masarati <ando@openldap.org>
Fri, 9 Jul 2004 18:32:00 +0000 (18:32 +0000)
CHANGES
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/search.c

diff --git a/CHANGES b/CHANGES
index db6596061f921acb90e7a539715aad93f1e31957..8bc7d643b3ef34c0c650e2e54486c3a7475d5bf9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,7 @@ OpenLDAP 2.2.15 Engineering
        Fixed back-bdb dbcache locking bug (ITS#3201)
        Fixed back-bdb ctxcsn locking bug
        Fixed back-ldap validate/pretty values (ITS#3218)
+       Fixed back-ldap shared connections failover (ITS#3217)
        Fixed slapd oidValidate 0 bug (ITS#3211)
        Fixed slapd uniqueMember/nameUID bugs (ITS#3210)
        Fixed slapd operational attribute log message bug (ITS#3205)
index 6e9de5f4e3002b8add9fbe8484c3afd913c6cdfd..a4df5890af7020814167bc57f2271ff5417e2233 100644 (file)
@@ -118,6 +118,7 @@ typedef struct dncookie {
 #endif
 } dncookie;
 
+int ldap_back_freeconn( Operation *op, struct ldapconn *lc );
 struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs);
 int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs);
 int ldap_back_map_result(SlapReply *rs);
index a4185efa6b28eac5eb82fb32d0cc7f9e9d0fe738..dc3ff1574edb04ccb76448a7f8c2504dbb305811 100644 (file)
@@ -209,6 +209,20 @@ static void myprint( Avlnode *root )
 }
 #endif /* PRINT_CONNTREE */
 
+int
+ldap_back_freeconn( Operation *op, struct ldapconn *lc )
+{
+       struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
+
+       ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+       lc = avl_delete( &li->conntree, (caddr_t)lc,
+                       ldap_back_conn_cmp );
+       ldap_back_conn_free( (void *)lc );
+       ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+
+       return 0;
+}
+
 struct ldapconn *
 ldap_back_getconn(Operation *op, SlapReply *rs)
 {
@@ -516,16 +530,16 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
        if ( ERR_OK( rs->sr_err ) ) {
                /* if result parsing fails, note the failure reason */
                if ( ldap_result( lc->ld, msgid, 1, NULL, &res ) == -1 ) {
-                       ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER,
-                                       &rs->sr_err);
+                       ldap_get_option( lc->ld, LDAP_OPT_ERROR_NUMBER,
+                                       &rs->sr_err );
 
                /* otherwise get the result; if it is not
                 * LDAP_SUCCESS, record it in the reply
                 * structure (this includes 
                 * LDAP_COMPARE_{TRUE|FALSE}) */
                } else {
-                       int rc = ldap_parse_result(lc->ld, res, &rs->sr_err,
-                                       &match, &text, NULL, NULL, 1);
+                       int rc = ldap_parse_result( lc->ld, res, &rs->sr_err,
+                                       &match, &text, NULL, NULL, 1 );
                        rs->sr_text = text;
                        if ( rc != LDAP_SUCCESS ) rs->sr_err = rc;
                }
index 4ba003666539e5f2f67f5f0ce9ed4633f0d40604..665c26ba109b5072e392916c389b791af790186d 100644 (file)
@@ -510,6 +510,9 @@ ldap_back_exop_whoami(
                        if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
                                ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER,
                                        &rs->sr_err);
+                               ldap_back_freeconn( op, lc );
+                               lc = NULL;
+
                        } else {
                                rs->sr_err = ldap_parse_whoami(lc->ld, res, &bv);
                                ldap_msgfree(res);
index 6f35c898a2cbfb613ef298eab16f6cab2e4f2230..ecd6f4dcafb2d848f9e88feeeb5a1b25b29488bd 100644 (file)
@@ -145,6 +145,9 @@ ldap_back_exop_passwd(
        if (rc == LDAP_SUCCESS) {
                if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
                        ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc);
+                       ldap_back_freeconn( op, lc );
+                       lc = NULL;
+
                } else {
                        /* sigh. parse twice, because parse_passwd doesn't give
                         * us the err / match / msg info.
index bce3827aad7e2277af49b2c232193cc0fdc39dc4..f88edeb943b1af425901ce523963590e93c72956 100644 (file)
@@ -58,6 +58,7 @@ ldap_back_search(
        struct berval mbase;
        struct berval mfilter = BER_BVNULL;
        int dontfreetext = 0;
+       int freeconn = 0;
        dncookie dc;
 #ifdef LDAP_BACK_PROXY_AUTHZ
        LDAPControl **ctrls = NULL;
@@ -77,11 +78,14 @@ ldap_back_search(
        }
 
        /* should we check return values? */
-       if (op->ors_deref != -1)
-               ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&op->ors_deref);
-       if (op->ors_tlimit != SLAP_NO_LIMIT) {
+       if ( op->ors_deref != -1 ) {
+               ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&op->ors_deref );
+       }
+
+       if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
                tv.tv_sec = op->ors_tlimit;
                tv.tv_usec = 0;
+
        } else {
                tv.tv_sec = 0;
        }
@@ -127,7 +131,7 @@ ldap_back_search(
        rs->sr_err = ldap_back_map_attrs( &li->rwmap.rwm_at,
                        op->ors_attrs,
                        BACKLDAP_MAP, &mapped_attrs );
-       if ( rs->sr_err ) {
+       if ( rs->sr_err != LDAP_SUCCESS ) {
                rc = -1;
                goto finish;
        }
@@ -140,7 +144,7 @@ ldap_back_search(
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
        
-       rs->sr_err = ldap_search_ext(lc->ld, mbase.bv_val,
+       rs->sr_err = ldap_search_ext( lc->ld, mbase.bv_val,
                        op->ors_scope, mfilter.bv_val,
                        mapped_attrs, op->ors_attrsonly,
 #ifdef LDAP_BACK_PROXY_AUTHZ
@@ -154,7 +158,11 @@ ldap_back_search(
 
        if ( rs->sr_err != LDAP_SUCCESS ) {
 fail:;
-               rc = ldap_back_op_result(lc, op, rs, msgid, 0);
+               rc = ldap_back_op_result( lc, op, rs, msgid, 0 );
+               if ( freeconn ) {
+                       ldap_back_freeconn( op, lc );
+                       lc = NULL;
+               }
                goto finish;
        }
 
@@ -163,27 +171,28 @@ fail:;
         * but this is necessary for version matching, and for ACL processing.
         */
 
-       for ( rc=0; rc != -1; rc = ldap_result(lc->ld, msgid, 0, &tv, &res))
+       for ( rc = 0; rc != -1; rc = ldap_result( lc->ld, msgid, 0, &tv, &res ) )
        {
                /* check for abandon */
-               if (op->o_abandon) {
-                       ldap_abandon(lc->ld, msgid);
+               if ( op->o_abandon ) {
+                       ldap_abandon( lc->ld, msgid );
                        rc = 0;
                        goto finish;
                }
 
-               if (rc == 0) {
+               if ( rc == 0 ) {
                        tv.tv_sec = 0;
                        tv.tv_usec = 100000;
                        ldap_pvt_thread_yield();
 
-               } else if (rc == LDAP_RES_SEARCH_ENTRY) {
+               } else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
                        Entry ent = {0};
                        struct berval bdn;
                        int abort = 0;
-                       e = ldap_first_entry(lc->ld,res);
-                       if ( ( rc = ldap_build_entry(op, e, &ent, &bdn,
-                                               LDAP_BUILD_ENTRY_PRIVATE)) == LDAP_SUCCESS ) {
+                       e = ldap_first_entry( lc->ld, res );
+                       rc = ldap_build_entry( op, e, &ent, &bdn,
+                                       LDAP_BUILD_ENTRY_PRIVATE );
+                      if ( rc == LDAP_SUCCESS ) {
                                rs->sr_entry = &ent;
                                rs->sr_attrs = op->ors_attrs;
                                rs->sr_flags = 0;
@@ -196,10 +205,12 @@ fail:;
                                        ent.e_attrs = a->a_next;
 
                                        v = a->a_vals;
-                                       if (a->a_vals != &dummy)
+                                       if ( a->a_vals != &dummy ) {
                                                ber_bvarray_free(a->a_vals);
-                                       if (a->a_nvals != v)
+                                       }
+                                       if ( a->a_nvals != v ) {
                                                ber_bvarray_free(a->a_nvals);
+                                       }
                                        ch_free(a);
                                }
                                
@@ -208,9 +219,9 @@ fail:;
                                if ( ent.e_ndn )
                                        free( ent.e_ndn );
                        }
-                       ldap_msgfree(res);
+                       ldap_msgfree( res );
                        if ( abort ) {
-                               ldap_abandon(lc->ld, msgid);
+                               ldap_abandon( lc->ld, msgid );
                                goto finish;
                        }
 
@@ -255,18 +266,24 @@ fail:;
                        }
 
                } else {
-                       rc = ldap_parse_result(lc->ld, res, &rs->sr_err,
+                       rc = ldap_parse_result( lc->ld, res, &rs->sr_err,
                                        &match.bv_val, (char **)&rs->sr_text,
-                                       NULL, NULL, 1);
-                       if (rc != LDAP_SUCCESS ) rs->sr_err = rc;
+                                       NULL, NULL, 1 );
+                       if (rc != LDAP_SUCCESS ) {
+                               rs->sr_err = rc;
+                       }
                        rs->sr_err = slap_map_api2result( rs );
                        rc = 0;
                        break;
                }
        }
 
-       if (rc == -1)
+       if ( rc == -1 ) {
+               /* FIXME: invalidate the connection? */
+               rs->sr_err = LDAP_SERVER_DOWN;
+               freeconn = 1;
                goto fail;
+       }
 
        /*
         * Rewrite the matched portion of the search base, if required
@@ -281,7 +298,7 @@ fail:;
                dc.normalized = 0;
 #endif
                match.bv_len = strlen( match.bv_val );
-               ldap_back_dn_massage(&dc, &match, &mdn);
+               ldap_back_dn_massage( &dc, &match, &mdn );
                rs->sr_matched = mdn.bv_val;
        }
        if ( rs->sr_v2ref ) {