]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-meta/bind.c
Drop unnecessary memset()s
[openldap] / servers / slapd / back-meta / bind.c
index ca85a9202c51a0dbeba9cf95682a7fd79c37c30b..0f450bef669f91bfcba697769825ada9b2aae134 100644 (file)
@@ -33,6 +33,8 @@
 #include "slap.h"
 #include "../back-ldap/back-ldap.h"
 #include "back-meta.h"
+#undef ldap_debug      /* silence a warning in ldap-int.h */
+#include "../../../libraries/libldap/ldap-int.h"
 
 #include "lutil_ldap.h"
 
@@ -166,9 +168,7 @@ meta_back_bind( Operation *op, SlapReply *rs )
                                        BER_BVZERO( &msc->msc_bound_ndn );
                                }
 
-                               if ( LDAP_BACK_SAVECRED( mi ) &&
-                                       !BER_BVISNULL( &msc->msc_cred ) )
-                               {
+                               if ( !BER_BVISNULL( &msc->msc_cred ) ) {
                                        /* destroy sensitive data */
                                        memset( msc->msc_cred.bv_val, 0,
                                                msc->msc_cred.bv_len );
@@ -219,6 +219,9 @@ retry_lock:;
                        }
 
                        assert( mc->mc_refcnt == 1 );
+#if META_BACK_PRINT_CONNTREE > 0
+                       meta_back_print_conntree( mi, ">>> meta_back_bind" );
+#endif /* META_BACK_PRINT_CONNTREE */
                        tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
                                meta_back_conndn_cmp );
                        assert( tmpmc == mc );
@@ -229,7 +232,7 @@ retry_lock:;
                                {
                                        Debug( LDAP_DEBUG_TRACE,
                                                "=>meta_back_bind: destroying conn %ld (refcnt=%u)\n",
-                                               LDAP_BACK_PCONN_ID( mc->mc_conn ), mc->mc_refcnt, 0 );
+                                               LDAP_BACK_PCONN_ID( mc ), mc->mc_refcnt, 0 );
 
                                        if ( tmpmc->mc_refcnt != 0 ) {
                                                /* taint it */
@@ -248,15 +251,18 @@ retry_lock:;
 
                        ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
                        if ( isroot ) {
-                               mc->mc_conn = LDAP_BACK_PCONN_SET( op );
+                               LDAP_BACK_CONN_ISPRIV_SET( mc );
+                               LDAP_BACK_PCONN_SET( mc, op );
                        }
                        lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
                                meta_back_conndn_cmp, meta_back_conndn_dup );
+#if META_BACK_PRINT_CONNTREE > 0
+                       meta_back_print_conntree( mi, "<<< meta_back_bind" );
+#endif /* META_BACK_PRINT_CONNTREE */
                        ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
                        if ( lerr == -1 ) {
-                               meta_clear_candidates( op, mc );
-
                                /* we can do this because mc_refcnt == 1 */
+                               assert( mc->mc_refcnt == 1 );
                                mc->mc_refcnt = 0;
                                meta_back_conn_free( mc );
                                mc = NULL;
@@ -319,6 +325,43 @@ meta_back_bind_op_result(
                op->o_log_prefix, candidate, 0 );
 
        if ( rs->sr_err == LDAP_SUCCESS ) {
+               time_t          stoptime = (time_t)(-1),
+                               timeout;
+               int             timeout_err = op->o_protocol >= LDAP_VERSION3 ?
+                               LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
+               const char      *timeout_text = "Operation timed out";
+               slap_op_t       opidx = slap_req2op( op->o_tag );
+
+               /* since timeout is not specified, compute and use
+                * the one specific to the ongoing operation */
+               if ( opidx == LDAP_REQ_SEARCH ) {
+                       if ( op->ors_tlimit <= 0 ) {
+                               timeout = 0;
+
+                       } else {
+                               timeout = op->ors_tlimit;
+                               timeout_err = LDAP_TIMELIMIT_EXCEEDED;
+                               timeout_text = NULL;
+                       }
+
+               } else {
+                       timeout = mt->mt_timeout[ opidx ];
+               }
+
+               /* better than nothing :) */
+               if ( timeout == 0 ) {
+                       if ( mi->mi_idle_timeout ) {
+                               timeout = mi->mi_idle_timeout;
+
+                       } else if ( mi->mi_conn_ttl ) {
+                               timeout = mi->mi_conn_ttl;
+                       }
+               }
+
+               if ( timeout ) {
+                       stoptime = op->o_time + timeout;
+               }
+
                LDAP_BACK_TV_SET( &tv );
 
                /*
@@ -328,11 +371,15 @@ retry:;
                rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
                switch ( rc ) {
                case 0:
+#if 0
                        Debug( LDAP_DEBUG_ANY,
                                "%s meta_back_bind_op_result[%d]: ldap_result=0 nretries=%d.\n",
                                op->o_log_prefix, candidate, nretries );
+#endif
 
-                       if ( nretries != META_RETRY_NEVER ) {
+                       if ( nretries != META_RETRY_NEVER 
+                               || ( timeout && slap_get_time() <= stoptime ) )
+                       {
                                ldap_pvt_thread_yield();
                                if ( nretries > 0 ) {
                                        nretries--;
@@ -341,20 +388,26 @@ retry:;
                                goto retry;
                        }
 
-                       /* FIXME: binds cannot be abandoned */
                        /* don't let anyone else use this handler,
                         * because there's a pending bind that will not
                         * be acknowledged */
                        ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
-                       ldap_unbind_ext( msc->msc_ld, NULL, NULL );
-                       msc->msc_ld = NULL;
-                       rs->sr_err = LDAP_BUSY;
-                       LDAP_BACK_CONN_BINDING_CLEAR( msc );
+                       assert( LDAP_BACK_CONN_BINDING( msc ) );
+
+#ifdef DEBUG_205
+                       Debug( LDAP_DEBUG_ANY, "### %s meta_back_bind_op_result ldap_unbind_ext[%d] ld=%p\n",
+                               op->o_log_prefix, candidate, (void *)msc->msc_ld );
+#endif /* DEBUG_205 */
+
+                       meta_clear_one_candidate( op, mc, candidate );
                        ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+
+                       rs->sr_err = timeout_err;
+                       rs->sr_text = timeout_text;
                        break;
 
                case -1:
-                       ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER,
+                       ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE,
                                &rs->sr_err );
 
                        snprintf( buf, sizeof( buf ),
@@ -414,7 +467,7 @@ meta_back_single_bind(
                BER_BVZERO( &msc->msc_bound_ndn );
        }
 
-       if ( LDAP_BACK_SAVECRED( mi ) && !BER_BVISNULL( &msc->msc_cred ) ) {
+       if ( !BER_BVISNULL( &msc->msc_cred ) ) {
                /* destroy sensitive data */
                memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
                ch_free( msc->msc_cred.bv_val );
@@ -466,6 +519,10 @@ meta_back_single_bind(
        mc->mc_authz_target = candidate;
 
        if ( LDAP_BACK_SAVECRED( mi ) ) {
+               if ( !BER_BVISNULL( &msc->msc_cred ) ) {
+                       memset( msc->msc_cred.bv_val, 0,
+                               msc->msc_cred.bv_len );
+               }
                ber_bvreplace( &msc->msc_cred, &op->orb_cred );
                ldap_set_rebind_proc( msc->msc_ld, mt->mt_rebind_f, msc );
        }
@@ -518,6 +575,7 @@ meta_back_single_dobind(
                !op->o_do_not_cache &&
                ( BER_BVISNULL( &msc->msc_bound_ndn ) ||
                        BER_BVISEMPTY( &msc->msc_bound_ndn ) ||
+                       ( LDAP_BACK_CONN_ISPRIV( mc ) && dn_match( &msc->msc_bound_ndn, &mt->mt_idassert_authcDN ) ) ||
                        ( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
        {
                (void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok );
@@ -584,7 +642,7 @@ meta_back_dobind(
        Debug( LDAP_DEBUG_TRACE,
                "%s meta_back_dobind: conn=%ld%s\n",
                op->o_log_prefix,
-               LDAP_BACK_PCONN_ID( mc->mc_conn ),
+               LDAP_BACK_PCONN_ID( mc ),
                isroot ? " (isroot)" : "" );
 
        /*
@@ -623,7 +681,8 @@ retry_binding:;
                        ++bound;
                        continue;
 
-               } else if ( LDAP_BACK_CONN_BINDING( msc ) ) {
+               } else if ( META_BACK_CONN_CREATING( msc ) || LDAP_BACK_CONN_BINDING( msc ) )
+               {
                        ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
                        ldap_pvt_thread_yield();
                        goto retry_binding;
@@ -650,7 +709,7 @@ retry_binding:;
 
 
                        if ( rc == LDAP_UNAVAILABLE ) {
-                               /* FIXME: meta_back_retry() already calls
+                               /* FIXME: meta_back_retry() already re-calls
                                 * meta_back_single_dobind() */
                                if ( meta_back_retry( op, rs, &mc, i, sendok ) ) {
                                        goto retry_ok;
@@ -660,6 +719,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 );
                                }
 
                                return 0;
@@ -715,7 +775,7 @@ retry_ok:;
 done:;
        Debug( LDAP_DEBUG_TRACE,
                "%s meta_back_dobind: conn=%ld bound=%d\n",
-               op->o_log_prefix, LDAP_BACK_PCONN_ID( mc->mc_conn ), bound );
+               op->o_log_prefix, LDAP_BACK_PCONN_ID( mc ), bound );
 
        if ( bound == 0 ) {
                meta_back_release_conn( op, mc );
@@ -816,7 +876,7 @@ meta_back_cancel(
                rc = ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL );
 
        } else if ( META_BACK_TGT_IGNORE( mt ) ) {
-               rc = LDAP_SUCCESS;
+               rc = ldap_pvt_discard( msc->msc_ld, msgid );
 
        } else if ( META_BACK_TGT_CANCEL( mt ) ) {
                rc = ldap_cancel_s( msc->msc_ld, msgid, NULL, NULL );
@@ -876,24 +936,55 @@ meta_back_op_result(
                        int             rc;
                        struct timeval  tv;
                        LDAPMessage     *res = NULL;
+                       time_t          stoptime = (time_t)(-1);
+                       int             timeout_err = op->o_protocol >= LDAP_VERSION3 ?
+                                               LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
+                       const char      *timeout_text = "Operation timed out";
 
-                       if ( timeout ) {
-                               tv.tv_sec = timeout;
-                               tv.tv_usec = 0;
+                       /* if timeout is not specified, compute and use
+                        * the one specific to the ongoing operation */
+                       if ( timeout == (time_t)(-1) ) {
+                               slap_op_t       opidx = slap_req2op( op->o_tag );
 
-                       } else {
-                               LDAP_BACK_TV_SET( &tv );
+                               if ( opidx == SLAP_OP_SEARCH ) {
+                                       if ( op->ors_tlimit <= 0 ) {
+                                               timeout = 0;
+
+                                       } else {
+                                               timeout = op->ors_tlimit;
+                                               timeout_err = LDAP_TIMELIMIT_EXCEEDED;
+                                               timeout_text = NULL;
+                                       }
+
+                               } else {
+                                       timeout = mt->mt_timeout[ opidx ];
+                               }
+                       }
+
+                       /* better than nothing :) */
+                       if ( timeout == 0 ) {
+                               if ( mi->mi_idle_timeout ) {
+                                       timeout = mi->mi_idle_timeout;
+
+                               } else if ( mi->mi_conn_ttl ) {
+                                       timeout = mi->mi_conn_ttl;
+                               }
                        }
 
+                       if ( timeout ) {
+                               stoptime = op->o_time + timeout;
+                       }
+
+                       LDAP_BACK_TV_SET( &tv );
+
 retry:;
                        rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
                        switch ( rc ) {
                        case 0:
-                               if ( timeout ) {
+                               if ( timeout && slap_get_time() > stoptime ) {
                                        (void)meta_back_cancel( mc, op, rs, msgid, candidate, sendok );
-                                       rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
-                                               LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
-                                       rs->sr_text = "Operation timed out";
+                                       rs->sr_err = timeout_err;
+                                       rs->sr_text = timeout_text;
                                        break;
                                }
 
@@ -902,7 +993,7 @@ retry:;
                                goto retry;
 
                        case -1:
-                               ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER,
+                               ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE,
                                                &rs->sr_err );
                                break;
 
@@ -975,7 +1066,7 @@ retry:;
 
                        rs->sr_err = LDAP_SUCCESS;
 
-                       ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER, &rs->sr_err );
+                       ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err );
                        if ( rs->sr_err != LDAP_SUCCESS ) {
                                /*
                                 * better check the type of error. In some cases
@@ -984,7 +1075,7 @@ retry:;
                                 * positive result ...
                                 */
                                ldap_get_option( msc->msc_ld,
-                                               LDAP_OPT_ERROR_STRING, &xtext );
+                                               LDAP_OPT_DIAGNOSTIC_MESSAGE, &xtext );
                                if ( xtext != NULL && xtext [ 0 ] == '\0' ) {
                                        ldap_memfree( xtext );
                                        xtext = NULL;