]> git.sur5r.net Git - openldap/commitdiff
ITS#3172 connection retry from HEAD
authorHoward Chu <hyc@openldap.org>
Sat, 25 Dec 2004 13:24:39 +0000 (13:24 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 25 Dec 2004 13:24:39 +0000 (13:24 +0000)
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/search.c

index 837f4d3a3afa2cd5d6c7440560621c689e7680c6..8af3b4ea85c2170cf7345c3910d84571c8d5331d 100644 (file)
@@ -46,9 +46,10 @@ ldap_back_add(
        ber_int_t msgid;
        dncookie dc;
        int isupdate;
+       int do_retry = 1;
+       int rc = LDAP_SUCCESS;
 #ifdef LDAP_BACK_PROXY_AUTHZ 
        LDAPControl **ctrls = NULL;
-       int rc = LDAP_SUCCESS;
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
 #ifdef NEW_LOGGING
@@ -131,10 +132,13 @@ ldap_back_add(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_add_ext(lc->ld, mdn.bv_val, attrs,
 #ifdef LDAP_BACK_PROXY_AUTHZ
                        ctrls,
@@ -142,7 +146,11 @@ ldap_back_add(
                        op->o_ctrls,
 #endif /* ! LDAP_BACK_PROXY_AUTHZ */
                        NULL, &msgid);
-
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry( lc, op, rs )) goto retry;
+       }
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
        if ( ctrls && ctrls != op->o_ctrls ) {
@@ -159,12 +167,6 @@ cleanup:
        if ( mdn.bv_val != op->o_req_dn.bv_val ) {
                free( mdn.bv_val );
        }
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-       return ldap_back_op_result( lc, op, rs, msgid, 1 ) != LDAP_SUCCESS;
+       return rc;
 }
 
index a4df5890af7020814167bc57f2271ff5417e2233..2d48898a8ffdd8a5d92484243b38489787096d9b 100644 (file)
@@ -121,6 +121,7 @@ typedef struct 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_retry(struct ldapconn *lc, Operation *op, SlapReply *rs);
 int ldap_back_map_result(SlapReply *rs);
 int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
        ber_int_t msgid, int sendok);
index dc3ff1574edb04ccb76448a7f8c2504dbb305811..7025fffce022472c00d7ef28891523e6ec004abc 100644 (file)
@@ -592,6 +592,39 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
        return( ERR_OK( rs->sr_err ) ? 0 : -1 );
 }
 
+/* return true if bound, false if failed */
+int
+ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs )
+{
+       struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+       int vers = op->o_protocol;
+       LDAP *ld;
+
+       ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
+       ldap_unbind( lc->ld );
+       lc->bound = 0;
+       rs->sr_err = ldap_initialize(&ld, li->url);
+               
+       if (rs->sr_err != LDAP_SUCCESS) {
+               rs->sr_err = slap_map_api2result( rs );
+               if (rs->sr_text == NULL) {
+                       rs->sr_text = "ldap_initialize() failed";
+               }
+               if (op->o_conn) send_ldap_result( op, rs );
+               rs->sr_text = NULL;
+               return 0;
+       }
+       /* Set LDAP version. This will always succeed: If the client
+        * bound with a particular version, then so can we.
+        */
+       ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers);
+       /* FIXME: configurable? */
+       ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON);
+       lc->ld = ld;
+       ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
+       return ldap_back_dobind( lc, op, rs );
+}
+
 #ifdef LDAP_BACK_PROXY_AUTHZ
 /*
  * ldap_back_proxy_authz_ctrl() prepends a proxyAuthz control
index f8d04d71ce6214a7735642b1529f440926fe7cbc..a44c78a66e211329549dddba5b0906bfe6d61b3c 100644 (file)
@@ -42,10 +42,11 @@ ldap_back_compare(
        struct berval mdn = BER_BVNULL;
        ber_int_t msgid;
        int freeval = 0;
+       int do_retry = 1;
+       int rc = LDAP_SUCCESS;
        dncookie dc;
 #ifdef LDAP_BACK_PROXY_AUTHZ 
        LDAPControl **ctrls = NULL;
-       int rc = LDAP_SUCCESS;
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
        lc = ldap_back_getconn(op, rs);
@@ -103,10 +104,13 @@ ldap_back_compare(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_compare_ext( lc->ld, mdn.bv_val,
                        mapped_at.bv_val, &mapped_val, 
 #ifdef LDAP_BACK_PROXY_AUTHZ
@@ -115,6 +119,11 @@ ldap_back_compare(
                        op->o_ctrls,
 #endif /* ! LDAP_BACK_PROXY_AUTHZ */
                        NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
@@ -131,11 +140,5 @@ cleanup:
                free( mapped_val.bv_val );
        }
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-       return( ldap_back_op_result( lc, op, rs, msgid, 1 ) );
+       return rc;
 }
index ecdb83a956a736d0a415a495dc7e85a5514729b9..373b8a72d39ac7456dcd63b559d05983047d227e 100644 (file)
@@ -519,6 +519,7 @@ ldap_back_exop_whoami(
                LDAPMessage *res;
                Operation op2 = *op;
                ber_int_t msgid;
+               int do_retry = 1;
 
                ctrls[0] = &c;
                op2.o_ndn = op->o_conn->c_ndn;
@@ -533,11 +534,17 @@ ldap_back_exop_whoami(
                strcpy(c.ldctl_value.bv_val, "dn:");
                strcpy(c.ldctl_value.bv_val+3, op->o_ndn.bv_val);
 
+retry:
                rs->sr_err = ldap_whoami(lc->ld, ctrls, NULL, &msgid);
                if (rs->sr_err == LDAP_SUCCESS) {
                        if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
                                ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER,
                                        &rs->sr_err);
+                               if ( rs->sr_err = LDAP_SERVER_DOWN && do_retry ) {
+                                       do_retry = 0;
+                                       if ( ldap_back_retry( lc, op, rs ))
+                                               goto retry;
+                               }
                                ldap_back_freeconn( op, lc );
                                lc = NULL;
 
index f7837f45f42080f63fe7b85141f76608d83dc9a7..2f58a9e23810780105fc0e3e22a5428e897e50a6 100644 (file)
@@ -40,9 +40,10 @@ ldap_back_delete(
        struct ldapconn *lc;
        ber_int_t msgid;
        dncookie dc;
+       int do_retry = 1;
+       int rc = LDAP_SUCCESS;
 #ifdef LDAP_BACK_PROXY_AUTHZ 
        LDAPControl **ctrls = NULL;
-       int rc = LDAP_SUCCESS;
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
        struct berval mdn = BER_BVNULL;
@@ -73,10 +74,13 @@ ldap_back_delete(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_delete_ext( lc->ld, mdn.bv_val,
 #ifdef LDAP_BACK_PROXY_AUTHZ
                        ctrls,
@@ -84,6 +88,11 @@ ldap_back_delete(
                        op->o_ctrls,
 #endif /* ! LDAP_BACK_PROXY_AUTHZ */
                        NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
@@ -97,12 +106,5 @@ cleanup:
                free( mdn.bv_val );
        }
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-       return( ldap_back_op_result( lc, op, rs, msgid, 1 ) );
+       return rc;
 }
index ecd6f4dcafb2d848f9e88feeeb5a1b25b29488bd..6ad8e11a47a6ab4fd81017eecc9f595f69142a53 100644 (file)
@@ -100,6 +100,7 @@ ldap_back_exop_passwd(
        LDAPMessage *res;
        ber_int_t msgid;
        int rc, isproxy;
+       int do_retry = 1;
        dncookie dc;
 
        lc = ldap_back_getconn(op, rs);
@@ -133,15 +134,12 @@ ldap_back_exop_passwd(
                }
        }
 
+retry:
        rc = ldap_passwd(lc->ld, isproxy ? &mdn : NULL,
                qpw->rs_old.bv_val ? &qpw->rs_old : NULL,
                qpw->rs_new.bv_val ? &qpw->rs_new : NULL,
                op->o_ctrls, NULL, &msgid);
 
-       if (mdn.bv_val != op->o_req_dn.bv_val) {
-               free(mdn.bv_val);
-       }
-
        if (rc == LDAP_SUCCESS) {
                if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
                        ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc);
@@ -171,6 +169,10 @@ ldap_back_exop_passwd(
        }
        if (rc != LDAP_SUCCESS) {
                rs->sr_err = slap_map_api2result( rs );
+               if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+                       do_retry = 0;
+                       if ( ldap_back_retry( lc, op, rs )) goto retry;
+               }
                send_ldap_result(op, rs);
                if (rs->sr_matched) free((char *)rs->sr_matched);
                if (rs->sr_text) free((char *)rs->sr_text);
@@ -178,5 +180,9 @@ ldap_back_exop_passwd(
                rs->sr_text = NULL;
                rc = -1;
        }
+       if (mdn.bv_val != op->o_req_dn.bv_val) {
+               free(mdn.bv_val);
+       }
+
        return rc;
 }
index 24b7617d606e54dc474eaa3a39c24f2debab1ac9..4a645eec8625f5de08080a96e400482590d20961 100644 (file)
@@ -47,6 +47,7 @@ ldap_back_modify(
        ber_int_t msgid;
        dncookie dc;
        int isupdate;
+       int do_retry = 1;
 #ifdef LDAP_BACK_PROXY_AUTHZ 
        LDAPControl **ctrls = NULL;
 #endif /* LDAP_BACK_PROXY_AUTHZ */
@@ -162,10 +163,13 @@ ldap_back_modify(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_modify_ext( lc->ld, mdn.bv_val, modv,
 #ifdef LDAP_BACK_PROXY_AUTHZ
                        ctrls,
@@ -173,6 +177,11 @@ ldap_back_modify(
                        op->o_ctrls,
 #endif /* ! LDAP_BACK_PROXY_AUTHZ */
                        NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 cleanup:;
 #ifdef LDAP_BACK_PROXY_AUTHZ
@@ -191,13 +200,6 @@ cleanup:;
        ch_free( mods );
        ch_free( modv );
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-       return ldap_back_op_result( lc, op, rs, msgid, 1 );
+       return rc;
 }
 
index 5a75d9d4b464fbfde4472fa1b1b58042730a2209..45dc6e19272536403d91dfb6f477f592ca01d708 100644 (file)
@@ -40,9 +40,10 @@ ldap_back_modrdn(
        struct ldapconn *lc;
        ber_int_t msgid;
        dncookie dc;
+       int do_retry = 1;
+       int rc = LDAP_SUCCESS;
 #ifdef LDAP_BACK_PROXY_AUTHZ 
        LDAPControl **ctrls = NULL;
-       int rc = LDAP_SUCCESS;
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
        struct berval mdn = BER_BVNULL, mnewSuperior = BER_BVNULL;
@@ -91,10 +92,13 @@ ldap_back_modrdn(
 #ifdef LDAP_BACK_PROXY_AUTHZ
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               rc = -1;
                goto cleanup;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
+retry:
        rs->sr_err = ldap_rename( lc->ld, mdn.bv_val,
                        op->orr_newrdn.bv_val, mnewSuperior.bv_val,
                        op->orr_deleteoldrdn,
@@ -104,6 +108,11 @@ ldap_back_modrdn(
                        op->o_ctrls,
 #endif /* ! LDAP_BACK_PROXY_AUTHZ */
                        NULL, &msgid );
+       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
+               do_retry = 0;
+               if ( ldap_back_retry (lc, op, rs )) goto retry;
+       }
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
@@ -121,13 +130,6 @@ cleanup:
                free( mnewSuperior.bv_val );
        }
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
-       }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-       return( ldap_back_op_result( lc, op, rs, msgid, 1 ) );
+       return rc;
 }
 
index 3e1631890b92ddcab29cc9df75c942f0d65170c8..7b02d6ab05e8e70b9c873f62250f541fd7181f86 100644 (file)
@@ -59,6 +59,7 @@ ldap_back_search(
        struct berval mfilter = BER_BVNULL;
        int dontfreetext = 0;
        int freeconn = 0;
+       int do_retry = 1;
        dncookie dc;
 #ifdef LDAP_BACK_PROXY_AUTHZ
        LDAPControl **ctrls = NULL;
@@ -143,7 +144,8 @@ ldap_back_search(
                goto finish;
        }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
-       
+
+retry:
        rs->sr_err = ldap_search_ext( lc->ld, mbase.bv_val,
                        op->ors_scope, mfilter.bv_val,
                        mapped_attrs, op->ors_attrsonly,
@@ -189,6 +191,8 @@ fail:;
                        Entry ent = {0};
                        struct berval bdn;
                        int abort = 0;
+                       do_retry = 0;
+
                        e = ldap_first_entry( lc->ld, res );
                        rc = ldap_build_entry( op, e, &ent, &bdn,
                                        LDAP_BUILD_ENTRY_PRIVATE );
@@ -229,6 +233,7 @@ fail:;
                        char            **references = NULL;
                        int             cnt;
 
+                       do_retry = 0;
                        rc = ldap_parse_reference( lc->ld, res,
                                        &references, &rs->sr_ctrls, 1 );
 
@@ -279,6 +284,11 @@ fail:;
        }
 
        if ( rc == -1 ) {
+               if ( do_retry ) {
+                       do_retry = 0;
+                       if ( ldap_back_retry( lc, op, rs ))
+                               goto retry;
+               }
                /* FIXME: invalidate the connection? */
                rs->sr_err = LDAP_SERVER_DOWN;
                freeconn = 1;
@@ -609,6 +619,7 @@ ldap_back_entry_get(
        Connection *oconn;
        SlapReply rs;
        dncookie dc;
+       int do_retry = 1;
 
        /* Tell getconn this is a privileged op */
        is_oc = op->o_do_not_cache;
@@ -646,17 +657,17 @@ ldap_back_entry_get(
                        rc = 1;
                        goto cleanup;
                }
+               is_oc = (strcasecmp("objectclass", mapped.bv_val) == 0);
+               if (oc && !is_oc) {
+                       gattr[0] = "objectclass";
+                       gattr[1] = mapped.bv_val;
+                       gattr[2] = NULL;
+               } else {
+                       gattr[0] = mapped.bv_val;
+                       gattr[1] = NULL;
+               }
        }
 
-       is_oc = (strcasecmp("objectclass", mapped.bv_val) == 0);
-       if (oc && !is_oc) {
-               gattr[0] = "objectclass";
-               gattr[1] = mapped.bv_val;
-               gattr[2] = NULL;
-       } else {
-               gattr[0] = mapped.bv_val;
-               gattr[1] = NULL;
-       }
        if (oc) {
                char *ptr;
                ldap_back_map(&li->rwmap.rwm_oc, &oc->soc_cname, &mapped,
@@ -668,10 +679,16 @@ ldap_back_entry_get(
                *ptr++ = '\0';
        }
 
-       if (ldap_search_ext_s(lc->ld, mdn.bv_val, LDAP_SCOPE_BASE, filter,
+retry:
+       rc = ldap_search_ext_s(lc->ld, mdn.bv_val, LDAP_SCOPE_BASE, filter,
                                gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
-                               LDAP_NO_LIMIT, &result) != LDAP_SUCCESS)
-       {
+                               LDAP_NO_LIMIT, &result);
+       if ( rc != LDAP_SUCCESS ) {
+               if ( rc == LDAP_SERVER_DOWN && do_retry ) {
+                       do_retry = 0;
+                       if ( ldap_back_retry( lc, op, &rs ))
+                               goto retry;
+               }
                goto cleanup;
        }