]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Fix a new backend not being operational if added via cn=config
authorNadezhda Ivanova <nivanova@symas.com>
Wed, 18 Apr 2018 14:55:30 +0000 (17:55 +0300)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:58:15 +0000 (17:58 +0000)
servers/lloadd/config.c
servers/lloadd/daemon.c
servers/lloadd/lload.h

index 9eb63910a430fc561964a569f28da4eae724e5cc..701eddc328285fb15afcf609227fe098f6e312d4 100644 (file)
@@ -751,9 +751,6 @@ config_generic( ConfigArgs *c )
     enum lcf_daemon flag = 0;
     int rc = LDAP_SUCCESS;
 
-    lload_change.type = c->op;
-    lload_change.object = LLOAD_DAEMON;
-
     if ( c->op == SLAP_CONFIG_EMIT ) {
         switch ( c->type ) {
             case CFG_IOTHREADS:
@@ -800,6 +797,9 @@ config_generic( ConfigArgs *c )
         return rc;
     }
 
+    lload_change.type = LLOAD_CHANGE_MODIFY;
+    lload_change.object = LLOAD_DAEMON;
+
     switch ( c->type ) {
         case CFG_CONCUR:
             ldap_pvt_thread_set_concurrency( c->value_uint );
@@ -1136,9 +1136,6 @@ config_bindconf( ConfigArgs *c )
 {
     int i;
 
-    lload_change.type = c->op;
-    lload_change.object = LLOAD_DAEMON;
-
     if ( c->op == SLAP_CONFIG_EMIT ) {
         struct berval bv;
 
@@ -1161,6 +1158,10 @@ config_bindconf( ConfigArgs *c )
         return LDAP_SUCCESS;
     }
 
+    lload_change.type = LLOAD_CHANGE_MODIFY;
+    lload_change.object = LLOAD_DAEMON;
+    lload_change.flags.daemon |= LLOAD_DAEMON_MOD_BINDCONF;
+
     for ( i = 1; i < c->argc; i++ ) {
         if ( lload_bindconf_parse( c->argv[i], &bindconf ) ) {
             Debug( LDAP_DEBUG_ANY, "config_bindconf: "
@@ -1821,16 +1822,18 @@ config_feature( ConfigArgs *c )
     slap_mask_t mask = 0;
     int i;
 
-    lload_change.type = c->op;
+    if ( c->op == SLAP_CONFIG_EMIT ) {
+        return mask_to_verbs( features, lload_features, &c->rvalue_vals );
+    }
+
+    lload_change.type = LLOAD_CHANGE_MODIFY;
     lload_change.object = LLOAD_DAEMON;
     lload_change.flags.daemon |= LLOAD_DAEMON_MOD_FEATURES;
     if ( !lload_change.target ) {
         lload_change.target = (void *)(uintptr_t)~lload_features;
     }
 
-    if ( c->op == SLAP_CONFIG_EMIT ) {
-        return mask_to_verbs( features, lload_features, &c->rvalue_vals );
-    } else if ( c->op == LDAP_MOD_DELETE ) {
+    if ( c->op == LDAP_MOD_DELETE ) {
         if ( !c->line ) {
             /* Last value has been deleted */
             lload_features = 0;
@@ -1883,14 +1886,10 @@ config_tls_cleanup( ConfigArgs *c )
 static int
 config_tls_option( ConfigArgs *c )
 {
-    int flag, rc;
+    int flag;
     int berval = 0;
     LDAP *ld = lload_tls_ld;
 
-    lload_change.type = c->op;
-    lload_change.object = LLOAD_DAEMON;
-    lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS;
-
     switch ( c->type ) {
         case CFG_TLS_RAND:
             flag = LDAP_OPT_X_TLS_RANDOM_FILE;
@@ -1943,16 +1942,19 @@ config_tls_option( ConfigArgs *c )
     if ( c->op == SLAP_CONFIG_EMIT ) {
         return ldap_pvt_tls_get_option( ld, flag,
                 berval ? (void *)&c->value_bv : (void *)&c->value_string );
-    } else if ( c->op == LDAP_MOD_DELETE ) {
-        config_push_cleanup( c, config_tls_cleanup );
+    }
+
+    lload_change.type = LLOAD_CHANGE_MODIFY;
+    lload_change.object = LLOAD_DAEMON;
+    lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS;
+
+    config_push_cleanup( c, config_tls_cleanup );
+    if ( c->op == LDAP_MOD_DELETE ) {
         return ldap_pvt_tls_set_option( ld, flag, NULL );
     }
     if ( !berval ) ch_free( c->value_string );
-    config_push_cleanup( c, config_tls_cleanup );
-    rc = ldap_pvt_tls_set_option(
+    return ldap_pvt_tls_set_option(
             ld, flag, berval ? (void *)&c->value_bv : (void *)c->argv[1] );
-    if ( berval ) ch_free( c->value_bv.bv_val );
-    return rc;
 }
 
 /* FIXME: this ought to be provided by libldap */
@@ -1961,10 +1963,6 @@ config_tls_config( ConfigArgs *c )
 {
     int i, flag;
 
-    lload_change.type = c->op;
-    lload_change.object = LLOAD_DAEMON;
-    lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS;
-
     switch ( c->type ) {
         case CFG_TLS_CRLCHECK:
             flag = LDAP_OPT_X_TLS_CRLCHECK;
@@ -1983,13 +1981,18 @@ config_tls_config( ConfigArgs *c )
     }
     if ( c->op == SLAP_CONFIG_EMIT ) {
         return lload_tls_get_config( lload_tls_ld, flag, &c->value_string );
-    } else if ( c->op == LDAP_MOD_DELETE ) {
+    }
+
+    lload_change.type = LLOAD_CHANGE_MODIFY;
+    lload_change.object = LLOAD_DAEMON;
+    lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS;
+
+    config_push_cleanup( c, config_tls_cleanup );
+    if ( c->op == LDAP_MOD_DELETE ) {
         int i = 0;
-        config_push_cleanup( c, config_tls_cleanup );
         return ldap_pvt_tls_set_option( lload_tls_ld, flag, &i );
     }
     ch_free( c->value_string );
-    config_push_cleanup( c, config_tls_cleanup );
     if ( isdigit( (unsigned char)c->argv[1][0] ) &&
             c->type != CFG_TLS_PROTOCOL_MIN ) {
         if ( lutil_atoi( &i, c->argv[1] ) != 0 ) {
@@ -3500,10 +3503,6 @@ backend_cf_gen( ConfigArgs *c )
 
     assert( b != NULL );
 
-    lload_change.type = c->op;
-    lload_change.object = LLOAD_BACKEND;
-    lload_change.target = b;
-
     if ( c->op == SLAP_CONFIG_EMIT ) {
         switch ( c->type ) {
             case CFG_URI:
@@ -3602,6 +3601,14 @@ backend_cf_gen( ConfigArgs *c )
             rc = 1;
             break;
     }
+
+    /* do not set this if it has already been set by another callback, e.g.
+     * lload_backend_ldadd */
+    if ( lload_change.type == LLOAD_CHANGE_UNDEFINED ) {
+        lload_change.type = LLOAD_CHANGE_MODIFY;
+    }
+    lload_change.object = LLOAD_BACKEND;
+    lload_change.target = b;
     lload_change.flags.backend |= flag;
 
     config_push_cleanup( c, lload_backend_finish );
@@ -3665,7 +3672,7 @@ lload_backend_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
      * save the new config when done with the entry */
     ca->lineno = 0;
 
-    lload_change.type = LDAP_REQ_ADD;
+    lload_change.type = LLOAD_CHANGE_ADD;
     lload_change.object = LLOAD_BACKEND;
     lload_change.target = b;
 
@@ -3678,7 +3685,7 @@ lload_backend_lddel( CfEntryInfo *ce, Operation *op )
 {
     LloadBackend *b = ce->ce_private;
 
-    lload_change.type = op->o_tag;
+    lload_change.type = LLOAD_CHANGE_DEL;
     lload_change.object = LLOAD_BACKEND;
     lload_change.target = b;
 
index 841d423e641b6761f2aa7cef87ac8372d456e35a..f0616c911d3f71ed3647f296f5752ff0cb8e8c0b 100644 (file)
@@ -1439,7 +1439,7 @@ daemon_wakeup_cb( evutil_socket_t sig, short what, void *arg )
     event_del( lload_daemon[tid].wakeup_event );
 }
 
-LloadChange lload_change = { .type = LLOAD_UNDEFINED };
+LloadChange lload_change = { .type = LLOAD_CHANGE_UNDEFINED };
 
 #ifdef BALANCER_MODULE
 int
@@ -1475,7 +1475,7 @@ lload_handle_backend_invalidation( LloadChange *change )
 
     assert( change->object == LLOAD_BACKEND );
 
-    if ( change->type == LDAP_REQ_ADD ) {
+    if ( change->type == LLOAD_CHANGE_ADD ) {
         BackendInfo *mi = backend_info( "monitor" );
 
         if ( mi ) {
@@ -1490,7 +1490,7 @@ lload_handle_backend_invalidation( LloadChange *change )
         }
         backend_retry( b );
         return;
-    } else if ( change->type == LDAP_REQ_DELETE ) {
+    } else if ( change->type == LLOAD_CHANGE_DEL ) {
         ldap_pvt_thread_pool_walk(
                 &connection_pool, handle_pdus, backend_conn_cb, b );
         ldap_pvt_thread_pool_walk(
@@ -1504,8 +1504,7 @@ lload_handle_backend_invalidation( LloadChange *change )
         lload_backend_destroy( b );
         return;
     }
-    assert( change->type == LDAP_REQ_MODIFY );
-    assert( change->flags.generic != 0 );
+    assert( change->type == LLOAD_CHANGE_MODIFY );
 
     /*
      * A change that can't be handled gracefully, terminate all connections and
@@ -1628,52 +1627,10 @@ lload_handle_backend_invalidation( LloadChange *change )
     }
 }
 
-void
-lload_handle_bindconf_invalidation( LloadChange *change )
-{
-    LloadBackend *b;
-    LloadConnection *c;
-
-    assert( change->type == LDAP_REQ_MODIFY );
-    assert( change->object == LLOAD_BINDCONF );
-
-    change->flags.bindconf &= ~LLOAD_BINDCONF_MOD_TIMEOUTS;
-
-    if ( !change->flags.bindconf ) {
-        /* Nothing needs doing, things will generally fall into place */
-        return;
-    }
-
-    /*
-     * Only timeout changes can be handled gracefully, terminate all
-     * connections and start over.
-     */
-    ldap_pvt_thread_pool_walk(
-            &connection_pool, handle_pdus, backend_conn_cb, NULL );
-    ldap_pvt_thread_pool_walk(
-            &connection_pool, upstream_bind, backend_conn_cb, NULL );
-
-    LDAP_CIRCLEQ_FOREACH ( b, &backend, b_next ) {
-        backend_reset( b );
-        backend_retry( b );
-    }
-
-    /* Reconsider the PRIVILEGED flag on all clients */
-    LDAP_CIRCLEQ_FOREACH ( c, &clients, c_next ) {
-        int privileged = ber_bvstrcasecmp( &c->c_auth, &lloadd_identity );
-
-        /* We have just terminated all pending operations (even pins), there
-         * should be no connections still binding/closing */
-        assert( c->c_state == LLOAD_C_READY );
-
-        c->c_type = privileged ? LLOAD_C_PRIVILEGED : LLOAD_C_OPEN;
-    }
-}
-
 void
 lload_handle_global_invalidation( LloadChange *change )
 {
-    assert( change->type == LDAP_REQ_MODIFY );
+    assert( change->type == LLOAD_CHANGE_MODIFY );
     assert( change->object == LLOAD_DAEMON );
 
     if ( change->flags.daemon & LLOAD_DAEMON_MOD_THREADS ) {
@@ -1747,12 +1704,45 @@ lload_handle_global_invalidation( LloadChange *change )
             }
         }
     }
+
+    if ( change->flags.daemon & LLOAD_DAEMON_MOD_BINDCONF ) {
+        LloadBackend *b;
+        LloadConnection *c;
+
+        /*
+         * Only timeout changes can be handled gracefully, terminate all
+         * connections and start over.
+         */
+        ldap_pvt_thread_pool_walk(
+                &connection_pool, handle_pdus, backend_conn_cb, NULL );
+        ldap_pvt_thread_pool_walk(
+                &connection_pool, upstream_bind, backend_conn_cb, NULL );
+
+        LDAP_CIRCLEQ_FOREACH ( b, &backend, b_next ) {
+            ldap_pvt_thread_mutex_lock( &b->b_mutex );
+            backend_reset( b );
+            backend_retry( b );
+            ldap_pvt_thread_mutex_unlock( &b->b_mutex );
+        }
+
+        /* Reconsider the PRIVILEGED flag on all clients */
+        LDAP_CIRCLEQ_FOREACH ( c, &clients, c_next ) {
+            int privileged = ber_bvstrcasecmp( &c->c_auth, &lloadd_identity );
+
+            /* We have just terminated all pending operations (even pins), there
+             * should be no connections still binding/closing */
+            assert( c->c_state == LLOAD_C_READY );
+
+            c->c_type = privileged ? LLOAD_C_PRIVILEGED : LLOAD_C_OPEN;
+        }
+    }
 }
 
 int
 lload_handle_invalidation( LloadChange *change )
 {
-    if ( change->type == LDAP_REQ_MODIFY && change->flags.generic == 0 ) {
+    if ( (change->type == LLOAD_CHANGE_MODIFY) &&
+            change->flags.generic == 0 ) {
         Debug( LDAP_DEBUG_ANY, "lload_handle_invalidation: "
                 "a modify where apparently nothing changed\n" );
     }
@@ -1764,9 +1754,6 @@ lload_handle_invalidation( LloadChange *change )
         case LLOAD_DAEMON:
             lload_handle_global_invalidation( change );
             break;
-        case LLOAD_BINDCONF:
-            lload_handle_bindconf_invalidation( change );
-            break;
         default:
             Debug( LDAP_DEBUG_ANY, "lload_handle_invalidation: "
                     "unrecognised change\n" );
@@ -1796,7 +1783,7 @@ lload_pause_base( struct event_base *base )
 void
 lload_pause_server( void )
 {
-    LloadChange ch = { .type = LLOAD_UNDEFINED };
+    LloadChange ch = { .type = LLOAD_CHANGE_UNDEFINED };
     int i;
 
     lload_pause_base( listener_base );
@@ -1812,7 +1799,7 @@ lload_pause_server( void )
 void
 lload_unpause_server( void )
 {
-    if ( lload_change.type != LLOAD_UNDEFINED ) {
+    if ( lload_change.type != LLOAD_CHANGE_UNDEFINED ) {
         lload_handle_invalidation( &lload_change );
     }
 
index ee2a5f4cc48dceb158524d4ded2abbf3c1e1ecb2..02e18b702e2c8a26c8d02505ece263455b78fecf 100644 (file)
@@ -106,10 +106,19 @@ typedef int lload_cf_aux_table_parse_x( struct berval *val,
 
 typedef struct LloadListener LloadListener;
 
+enum lc_type {
+    LLOAD_CHANGE_UNDEFINED = 0,
+    LLOAD_CHANGE_MODIFY,
+    LLOAD_CHANGE_ADD,
+    LLOAD_CHANGE_DEL,
+};
+
 enum lc_object {
     LLOAD_UNDEFINED = 0,
     LLOAD_DAEMON,
+    /*
     LLOAD_BINDCONF,
+    */
     LLOAD_BACKEND,
 };
 
@@ -119,10 +128,7 @@ enum lcf_daemon {
     LLOAD_DAEMON_MOD_TLS = 1 << 2,
     LLOAD_DAEMON_MOD_LISTENER_ADD = 1 << 3,
     LLOAD_DAEMON_MOD_LISTENER_REPLACE = 1 << 4,
-};
-
-enum lcf_bindconf {
-    LLOAD_BINDCONF_MOD_TIMEOUTS = 1 << 0,
+    LLOAD_DAEMON_MOD_BINDCONF = 1 << 5,
 };
 
 enum lcf_backend {
@@ -131,12 +137,11 @@ enum lcf_backend {
 };
 
 struct LloadChange {
-    ber_tag_t type;
+    enum lc_type type;
     enum lc_object object;
     union {
         int generic;
         enum lcf_daemon daemon;
-        enum lcf_bindconf bindconf;
         enum lcf_backend backend;
     } flags;
     void *target;