]> git.sur5r.net Git - openldap/commitdiff
make sure non-anonymous bind uses DN and creds (ITS#6574)
authorPierangelo Masarati <ando@openldap.org>
Wed, 23 Jun 2010 00:13:50 +0000 (00:13 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 23 Jun 2010 00:13:50 +0000 (00:13 +0000)
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/conn.c

index 7c89bee1898bf2287c22f68dfee07c9d638f6663..55c088bd6b0de6ca1ed054ff1d774971a6d25ba9 100644 (file)
@@ -586,7 +586,6 @@ meta_back_single_dobind(
        metatarget_t            *mt = mi->mi_targets[ candidate ];
        metaconn_t              *mc = *mcp;
        metasingleconn_t        *msc = &mc->mc_conns[ candidate ];
-       static struct berval    cred = BER_BVC( "" );
        int                     msgid;
 
        assert( !LDAP_BACK_CONN_ISBOUND( msc ) );
@@ -602,12 +601,22 @@ meta_back_single_dobind(
                (void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok );
 
        } else {
+               char *binddn = "";
+               struct berval cred = BER_BVC( "" );
+
+               /* use credentials if available */
+               if ( !BER_BVISNULL( &msc->msc_bound_ndn )
+                       && !BER_BVISNULL( &msc->msc_cred ) )
+               {
+                       binddn = msc->msc_bound_ndn.bv_val;
+                       cred = msc->msc_cred;
+               }
 
                /* FIXME: should we check if at least some of the op->o_ctrls
                 * can/should be passed? */
                for (;;) {
                        rs->sr_err = ldap_sasl_bind( msc->msc_ld,
-                               "", LDAP_SASL_SIMPLE, &cred,
+                               binddn, LDAP_SASL_SIMPLE, &cred,
                                NULL, NULL, &msgid );
                        if ( rs->sr_err != LDAP_X_CONNECTING ) {
                                break;
@@ -616,15 +625,26 @@ meta_back_single_dobind(
                }
 
                rs->sr_err = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok );
+
+               /* if bind succeeded, but anonymous, clear msc_bound_ndn */
+               if ( rs->sr_err == LDAP_SUCCESS ) {
+                       if ( binddn[0] == '\0' &&
+                               !BER_BVISNULL( &msc->msc_bound_ndn ) && 
+                               !BER_BVISEMPTY( &msc->msc_bound_ndn ) )
+                       {
+                               ber_memfree( msc->msc_bound_ndn.bv_val );
+                               BER_BVZERO( &msc->msc_bound_ndn );
+                       }
+               }
        }
 
        if ( rs->sr_err != LDAP_SUCCESS ) {
                if ( dolock ) {
                        ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
                }
-               LDAP_BACK_CONN_BINDING_CLEAR( msc );
+               LDAP_BACK_CONN_BINDING_CLEAR( msc );
                if ( META_BACK_ONERR_STOP( mi ) ) {
-                       LDAP_BACK_CONN_TAINTED_SET( mc );
+                       LDAP_BACK_CONN_TAINTED_SET( mc );
                        meta_back_release_conn_lock( mi, mc, 0 );
                        *mcp = NULL;
                }
@@ -1124,6 +1144,10 @@ retry:;
                        char                    *xtext = NULL;
                        char                    *xmatched = NULL;
 
+                       if ( msc->msc_ld == NULL ) {
+                               continue;
+                       }
+
                        rs->sr_err = LDAP_SUCCESS;
 
                        ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err );
@@ -1514,6 +1538,11 @@ meta_back_proxy_authz_cred(
        }
 
 done:;
+
+       if ( !BER_BVISEMPTY( binddn ) ) {
+               LDAP_BACK_CONN_ISIDASSERT_SET( msc );
+       }
+
        return rs->sr_err;
 }
 
index ca5b7932c380ff1f616ccb30411261273ccb40d5..c8fe33ae1c2927b31113d3b49b46f5ff61191336 100644 (file)
@@ -572,6 +572,7 @@ retry:;
                                }
                                ber_bvreplace( &msc->msc_cred, &mt->mt_idassert_passwd );
                        }
+                       LDAP_BACK_CONN_ISIDASSERT_SET( msc );
 
                } else {
                        ber_bvreplace( &msc->msc_bound_ndn, &slap_empty_bv );
@@ -685,6 +686,8 @@ meta_back_retry(
 
        assert( mc->mc_refcnt > 0 );
        if ( mc->mc_refcnt == 1 ) {
+               struct berval save_cred;
+
                if ( LogTest( LDAP_DEBUG_ANY ) ) {
                        char    buf[ SLAP_TEXT_BUFLEN ];
 
@@ -703,6 +706,11 @@ meta_back_retry(
                                op->o_log_prefix, candidate, buf );
                }
 
+               /* save credentials, if any, for later use;
+                * meta_clear_one_candidate() would free them */
+               save_cred = msc->msc_cred;
+               BER_BVZERO( &msc->msc_cred );
+
                meta_clear_one_candidate( op, mc, candidate );
                LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
@@ -712,6 +720,17 @@ meta_back_retry(
                rc = meta_back_init_one_conn( op, rs, mc, candidate,
                        LDAP_BACK_CONN_ISPRIV( mc ), sendok, 0 );
 
+               /* restore credentials, if any;
+                * meta_back_init_one_conn() restores msc_bound_ndn, if any;
+                * if no msc_bound_ndn is restored, destroy credentials */
+               if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
+                       msc->msc_cred = save_cred;
+
+               } else if ( !BER_BVISNULL( &save_cred ) ) {
+                       memset( save_cred.bv_val, 0, save_cred.bv_len );
+                       ber_memfree( save_cred.bv_val );
+               }
+
                /* restore the "binding" flag, in case */
                if ( binding ) {
                        LDAP_BACK_CONN_BINDING_SET( msc );
@@ -1095,6 +1114,7 @@ retry_lock:;
                        }
 
                        if ( mc != NULL ) {
+                               /* move to tail of queue */
                                if ( mc != LDAP_TAILQ_LAST( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
                                        metaconn_t, mc_q ) )
                                {