]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Fix proxyauthz handling
authorOndřej Kuzník <ondra@mistotebe.net>
Fri, 14 Apr 2017 08:36:42 +0000 (09:36 +0100)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:55:46 +0000 (17:55 +0000)
servers/lloadd/bind.c
servers/lloadd/operation.c
servers/lloadd/upstream.c

index a0359ab13262ed0dd258a258928564f2d2fd59ca..bcdb3e11192811e99fbb212c0378a509f3373407 100644 (file)
 #include "lutil.h"
 #include "slap.h"
 
+/*
+ * We hold op->o_upstream->c_io_mutex on entering the function.
+ */
 static int
 request_bind( Operation *op )
 {
-    Connection *c = op->o_upstream;
+    Connection *client = op->o_client, *upstream = op->o_upstream;
     BerElement *ber, *copy = NULL;
     BerValue binddn;
     ber_tag_t tag;
     ber_int_t version;
 
-    ber = c->c_pendingber;
+    ber = upstream->c_pendingber;
     if ( ber == NULL && (ber = ber_alloc()) == NULL ) {
         Debug( LDAP_DEBUG_ANY, "request_bind: "
                 "ber_alloc failed\n" );
         goto fail;
     }
-    c->c_pendingber = ber;
+    upstream->c_pendingber = ber;
 
     if ( (copy = ber_alloc()) == NULL ) {
         goto fail;
@@ -50,7 +53,7 @@ request_bind( Operation *op )
     if ( tag == LBER_ERROR ) {
         goto fail;
     } else if ( version != LDAP_VERSION3 ) {
-        /* TODO: result code and message */
+        ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
         operation_send_reject(
                 op, LDAP_PROTOCOL_ERROR, "LDAP version unsupported" );
         ber_free( copy, 0 );
@@ -62,55 +65,61 @@ request_bind( Operation *op )
         goto fail;
     }
 
-    ldap_pvt_thread_mutex_lock( &c->c_mutex );
-    if ( !BER_BVISNULL( &c->c_auth ) ) {
-        ber_memfree( c->c_auth.bv_val );
+    ldap_pvt_thread_mutex_lock( &client->c_mutex );
+    if ( !BER_BVISNULL( &client->c_auth ) ) {
+        ch_free( client->c_auth.bv_val );
     }
 
     if ( !BER_BVISEMPTY( &binddn ) ) {
         char *ptr;
-        c->c_auth.bv_len = STRLENOF("dn:") + binddn.bv_len;
-        c->c_auth.bv_val = ch_malloc( c->c_auth.bv_len + 1 );
+        client->c_auth.bv_len = STRLENOF("dn:") + binddn.bv_len;
+        client->c_auth.bv_val = ch_malloc( client->c_auth.bv_len + 1 );
 
-        ptr = lutil_strcopy( c->c_auth.bv_val, "dn:" );
+        ptr = lutil_strcopy( client->c_auth.bv_val, "dn:" );
         ptr = lutil_strncopy( ptr, binddn.bv_val, binddn.bv_len );
         *ptr = '\0';
     } else {
-        BER_BVZERO( &c->c_auth );
+        BER_BVZERO( &client->c_auth );
     }
+    ldap_pvt_thread_mutex_unlock( &client->c_mutex );
 
-    op->o_upstream_msgid = c->c_next_msgid++;
+    ldap_pvt_thread_mutex_lock( &upstream->c_mutex );
+    op->o_upstream_msgid = upstream->c_next_msgid++;
 
     ber_printf( ber, "t{titOtO}", LDAP_TAG_MESSAGE,
             LDAP_TAG_MSGID, op->o_upstream_msgid,
             LDAP_REQ_BIND, &op->o_request,
             LDAP_TAG_CONTROLS, BER_BV_OPTIONAL( &op->o_ctrls ) );
 
-    if ( tavl_insert( &c->c_ops, op, operation_upstream_cmp, avl_dup_error ) ) {
+    if ( tavl_insert( &upstream->c_ops, op, operation_upstream_cmp,
+                 avl_dup_error ) ) {
         assert(0);
     }
-    ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_mutex );
 
-    ldap_pvt_thread_mutex_unlock( &c->c_io_mutex );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
 
     ber_free( copy, 0 );
-    upstream_write_cb( -1, 0, c );
+    upstream_write_cb( -1, 0, upstream );
     return 0;
 
 fail:
     if ( copy ) {
         ber_free( copy, 0 );
     }
-    ldap_pvt_thread_mutex_unlock( &c->c_io_mutex );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
     ldap_pvt_thread_mutex_lock( &op->o_client->c_mutex );
     client_destroy( op->o_client );
     return 1;
 }
 
+/*
+ * We hold op->o_upstream->c_io_mutex on entering the function.
+ */
 static int
 request_bind_as_vc( Operation *op )
 {
-    Connection *c = op->o_upstream;
+    Connection *client = op->o_client, *upstream = op->o_upstream;
     BerElement *ber, *request, *copy = NULL;
     BerValue binddn, auth, mech;
     ber_int_t version;
@@ -137,79 +146,87 @@ request_bind_as_vc( Operation *op )
         goto fail;
     }
 
-    ber = c->c_pendingber;
+    ber = upstream->c_pendingber;
     if ( ber == NULL && (ber = ber_alloc()) == NULL ) {
         Debug( LDAP_DEBUG_ANY, "request_bind_as_vc: "
                 "ber_alloc failed\n" );
         goto fail;
     }
-    c->c_pendingber = ber;
+    upstream->c_pendingber = ber;
 
-    op->o_upstream_msgid = c->c_next_msgid++;
+    op->o_upstream_msgid = upstream->c_next_msgid++;
 
-    ldap_pvt_thread_mutex_lock( &c->c_mutex );
+    ldap_pvt_thread_mutex_lock( &upstream->c_mutex );
     ber_printf( ber, "t{tit{tst{{tOOtOtO}}}}", LDAP_TAG_MESSAGE,
             LDAP_TAG_MSGID, op->o_upstream_msgid,
             LDAP_REQ_EXTENDED,
             LDAP_TAG_EXOP_REQ_OID, LDAP_EXOP_VERIFY_CREDENTIALS,
             LDAP_TAG_EXOP_REQ_VALUE,
-            LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, BER_BV_OPTIONAL( &c->c_vc_cookie ),
+            LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, BER_BV_OPTIONAL( &upstream->c_vc_cookie ),
             &binddn, tag, &auth,
             LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS, BER_BV_OPTIONAL( &op->o_ctrls ) );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_mutex );
 
     tag = ber_peek_tag( copy, &len );
     switch ( tag ) {
         case LDAP_AUTH_SASL:
             ber_get_stringbv( copy, &mech, LBER_BV_NOTERM );
-            if ( ber_bvcmp( &mech, &c->c_sasl_bind_mech ) ) {
-                ber_memfree( c->c_sasl_bind_mech.bv_val );
-                ber_dupbv( &c->c_sasl_bind_mech, &mech );
+
+            ldap_pvt_thread_mutex_lock( &client->c_mutex );
+            if ( ber_bvcmp( &mech, &client->c_sasl_bind_mech ) ) {
+                ber_memfree( client->c_sasl_bind_mech.bv_val );
+                ber_dupbv( &client->c_sasl_bind_mech, &mech );
             }
+            ldap_pvt_thread_mutex_unlock( &client->c_mutex );
             /* TODO: extract authzdn from the message */
             break;
         case LDAP_AUTH_SIMPLE:
-            if ( !BER_BVISNULL( &c->c_auth ) ) {
-                ber_memfree( c->c_auth.bv_val );
+            ldap_pvt_thread_mutex_lock( &client->c_mutex );
+            if ( !BER_BVISNULL( &client->c_auth ) ) {
+                ch_free( client->c_auth.bv_val );
             }
             if ( !BER_BVISEMPTY( &binddn ) ) {
                 char *ptr;
-                c->c_auth.bv_len = STRLENOF("dn:") + binddn.bv_len;
-                c->c_auth.bv_val = ch_malloc( c->c_auth.bv_len + 1 );
+                client->c_auth.bv_len = STRLENOF("dn:") + binddn.bv_len;
+                client->c_auth.bv_val = ch_malloc( client->c_auth.bv_len + 1 );
 
-                ptr = lutil_strcopy( c->c_auth.bv_val, "dn:" );
+                ptr = lutil_strcopy( client->c_auth.bv_val, "dn:" );
                 ptr = lutil_strncopy( ptr, binddn.bv_val, binddn.bv_len );
                 *ptr = '\0';
             } else {
-                BER_BVZERO( &c->c_auth );
+                BER_BVZERO( &client->c_auth );
             }
 
-            if ( !BER_BVISNULL( &c->c_sasl_bind_mech ) ) {
-                ber_memfree( c->c_sasl_bind_mech.bv_val );
-                BER_BVZERO( &c->c_sasl_bind_mech );
+            if ( !BER_BVISNULL( &client->c_sasl_bind_mech ) ) {
+                ber_memfree( client->c_sasl_bind_mech.bv_val );
+                BER_BVZERO( &client->c_sasl_bind_mech );
             }
+            ldap_pvt_thread_mutex_unlock( &client->c_mutex );
             break;
         default:
-            ldap_pvt_thread_mutex_unlock( &c->c_mutex );
             goto fail;
     }
-    if ( tavl_insert( &c->c_ops, op, operation_upstream_cmp, avl_dup_error ) ) {
+
+    ldap_pvt_thread_mutex_lock( &upstream->c_mutex );
+    if ( tavl_insert( &upstream->c_ops, op, operation_upstream_cmp,
+                 avl_dup_error ) ) {
         assert(0);
     }
-    ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_mutex );
 
-    ldap_pvt_thread_mutex_unlock( &c->c_io_mutex );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
 
     ber_free( copy, 0 );
-    upstream_write_cb( -1, 0, c );
+    upstream_write_cb( -1, 0, upstream );
     return 0;
 
 fail:
     if ( copy ) {
         ber_free( copy, 0 );
     }
-    ldap_pvt_thread_mutex_unlock( &c->c_io_mutex );
-    ldap_pvt_thread_mutex_lock( &op->o_client->c_mutex );
-    client_destroy( op->o_client );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
+    ldap_pvt_thread_mutex_lock( &client->c_mutex );
+    client_destroy( client );
     return 1;
 }
 
@@ -229,6 +246,14 @@ client_reset( void *ctx, void *arg )
         c->c_state = SLAP_C_BINDING;
         destroy = 0;
     }
+    if ( !BER_BVISNULL( &c->c_auth ) ) {
+        ch_free( c->c_auth.bv_val );
+        BER_BVZERO( &c->c_auth );
+    }
+    if ( !BER_BVISNULL( &c->c_sasl_bind_mech ) ) {
+        ch_free( c->c_sasl_bind_mech.bv_val );
+        BER_BVZERO( &c->c_sasl_bind_mech );
+    }
     ldap_pvt_thread_mutex_unlock( &c->c_mutex );
 
     tavl_delete( &root, op, operation_client_cmp );
index d2083442f21b3b8ae1970a01281690092e21d898..e8cc3a0a9c932830367bf45a5322f4052b4e268f 100644 (file)
@@ -276,38 +276,42 @@ request_process( void *ctx, void *arg )
 {
     Operation *op = arg;
     BerElement *output;
-    Connection *c;
+    Connection *client = op->o_client, *upstream;
     ber_int_t msgid;
     int rc;
 
-    c = backend_select( op );
-    if ( !c ) {
+    upstream = backend_select( op );
+    if ( !upstream ) {
         Debug( LDAP_DEBUG_STATS, "request_process: "
                 "no available connection found\n" );
         goto fail;
     }
-    op->o_upstream = c;
+    op->o_upstream = upstream;
 
-    output = c->c_pendingber;
+    output = upstream->c_pendingber;
     if ( output == NULL && (output = ber_alloc()) == NULL ) {
         goto fail;
     }
-    c->c_pendingber = output;
+    upstream->c_pendingber = output;
 
-    ldap_pvt_thread_mutex_lock( &c->c_mutex );
-    op->o_upstream_msgid = msgid = c->c_next_msgid++;
-    rc = tavl_insert( &c->c_ops, op, operation_upstream_cmp, avl_dup_error );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_mutex );
+    op->o_upstream_msgid = msgid = upstream->c_next_msgid++;
+    rc = tavl_insert(
+            &upstream->c_ops, op, operation_upstream_cmp, avl_dup_error );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_mutex );
     assert( rc == LDAP_SUCCESS );
 
     if ( lload_features & LLOAD_FEATURE_PROXYAUTHZ ) {
+        ldap_pvt_thread_mutex_lock( &client->c_mutex );
         Debug( LDAP_DEBUG_TRACE, "request_process: "
                 "proxying identity %s to upstream\n",
-                c->c_auth.bv_val );
+                client->c_auth.bv_val );
         ber_printf( output, "t{titOt{{sbO}" /* "}}" */, LDAP_TAG_MESSAGE,
                 LDAP_TAG_MSGID, msgid,
                 op->o_tag, &op->o_request,
                 LDAP_TAG_CONTROLS,
-                LDAP_CONTROL_PROXY_AUTHZ, 1, &c->c_auth );
+                LDAP_CONTROL_PROXY_AUTHZ, 1, &client->c_auth );
+        ldap_pvt_thread_mutex_unlock( &client->c_mutex );
 
         if ( !BER_BVISNULL( &op->o_ctrls ) ) {
             BerElement *control_ber = ber_alloc();
@@ -329,13 +333,16 @@ request_process( void *ctx, void *arg )
                 op->o_tag, &op->o_request,
                 LDAP_TAG_CONTROLS, BER_BV_OPTIONAL( &op->o_ctrls ) );
     }
-    ldap_pvt_thread_mutex_unlock( &c->c_mutex );
-    ldap_pvt_thread_mutex_unlock( &c->c_io_mutex );
+    ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
 
-    upstream_write_cb( -1, 0, c );
+    upstream_write_cb( -1, 0, upstream );
 
     return NULL;
+
 fail:
+    if ( upstream ) {
+        ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
+    }
     operation_send_reject( op, LDAP_OTHER, "internal error" );
     return NULL;
 }
index e5bfd657fb6d4b71860b93a1ff5dc76f5eb364a4..611801e081543910152b655dacdc7840022e0d97 100644 (file)
@@ -155,11 +155,14 @@ handle_vc_bind_response( Operation *op, BerElement *ber )
 
     tag = ber_peek_tag( ber, &len );
     if ( result == LDAP_PROTOCOL_ERROR ) {
-        Backend *b = op->o_upstream->c_private;
-        ldap_pvt_thread_mutex_lock( &op->o_upstream->c_mutex );
+        Connection *upstream = op->o_upstream;
+        Backend *b;
+
+        ldap_pvt_thread_mutex_lock( &upstream->c_mutex );
+        b = (Backend *)upstream->c_private;
         Debug( LDAP_DEBUG_ANY, "VC extended operation not supported on backend %s\n",
                 b->b_bindconf.sb_uri.bv_val );
-        ldap_pvt_thread_mutex_unlock( &op->o_upstream->c_mutex );
+        ldap_pvt_thread_mutex_unlock( &upstream->c_mutex );
     }
 
     ldap_pvt_thread_mutex_lock( &c->c_mutex );