]> git.sur5r.net Git - openldap/commitdiff
clear shared connections when ldap_result fails with -1 (typically, remote server...
authorPierangelo Masarati <ando@openldap.org>
Sun, 4 Jul 2004 23:35:18 +0000 (23:35 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 4 Jul 2004 23:35:18 +0000 (23:35 +0000)
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

index 55358621b05886486888a603838df0eff57c54a0..44203222865cdaf0c3aea843134e6d2293dd0179 100644 (file)
@@ -164,6 +164,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 c11d87f5a808a050ad03149dcf4d2f10cea9815e..5d21a3c5810f60750888249cbc179651874a1cd1 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)
 {
@@ -645,16 +659,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 44167c6a76465d437226dde6ba48025f912a6fdd..88467b3f35a6eb0c81120c59be06e631116d7c91 100644 (file)
@@ -501,6 +501,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 7fc6cefc816bb9a96f52dc7935c5359362d21274..f2c552bc16d05d727b08ba51992bd7e8080fbbde 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;
        LDAPControl **ctrls = NULL;
 
@@ -75,11 +76,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;
        }
@@ -125,7 +129,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;
        }
@@ -139,7 +143,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,
                        ctrls, NULL,
@@ -148,7 +152,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;
        }
 
@@ -157,27 +165,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;
@@ -190,10 +199,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);
                                }
                                
@@ -202,9 +213,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;
                        }
 
@@ -249,18 +260,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
@@ -275,7 +292,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 ) {