]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/bconfig.c
ITS#4088 force cursors to use same locker
[openldap] / servers / slapd / bconfig.c
index 0e150188f3ab55959f6013146914b9ba391e2970..ea679bad6e82aae6400cb92eb9a533a4b139a368 100644 (file)
@@ -105,6 +105,7 @@ static ConfigDriver config_schema_dn;
 static ConfigDriver config_sizelimit;
 static ConfigDriver config_timelimit;
 static ConfigDriver config_overlay;
+static ConfigDriver config_subordinate; 
 static ConfigDriver config_suffix; 
 static ConfigDriver config_rootdn;
 static ConfigDriver config_rootpw;
@@ -135,6 +136,7 @@ enum {
        CFG_TLS_CERT_KEY,
        CFG_TLS_CA_PATH,
        CFG_TLS_CA_FILE,
+       CFG_TLS_DH_DIR,
        CFG_TLS_VERIFY,
        CFG_TLS_CRLCHECK,
        CFG_CONCUR,
@@ -392,7 +394,7 @@ static ConfigTable config_back_cf_table[] = {
                        "SUP labeledURI SINGLE-VALUE )", NULL, NULL },
        { "replica", "host or uri", 2, 0, 0, ARG_DB|ARG_MAGIC,
                &config_replica, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
-                       "SUP labeledURI )", NULL, NULL },
+                       "SUP labeledURI X-ORDERED 'VALUES' )", NULL, NULL },
        { "replica-argsfile", NULL, 0, 0, 0, ARG_STRING,
                &replica_argsFile, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
@@ -481,6 +483,9 @@ static ConfigTable config_back_cf_table[] = {
 #endif
                "( OLcfgGlAt:63 NAME 'olcSrvtab' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "subordinate", "[advertise]", 1, 2, 0, ARG_DB|ARG_MAGIC,
+               &config_subordinate, "( OLcfgDbAt:0.15 NAME 'olcSubordinate' "
+                       "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "suffix",     "suffix", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
                &config_suffix, "( OLcfgDbAt:0.10 NAME 'olcSuffix' "
                        "SYNTAX OMsDN )", NULL, NULL },
@@ -557,6 +562,14 @@ static ConfigTable config_back_cf_table[] = {
 #endif
                "( OLcfgGlAt:75 NAME 'olcTLSVerifyClient' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "TLSDHParamDir", NULL, 0, 0, 0,
+#ifdef HAVE_TLS
+               CFG_TLS_DH_DIR|ARG_STRING|ARG_MAGIC, &config_tls_option,
+#else
+               ARG_IGNORED, NULL,
+#endif
+               "( OLcfgGlAt:77 NAME 'olcTLSDHParamDir' "
+                       "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
        { "ucdata-path", "path", 2, 2, 0, ARG_IGNORED,
                NULL, NULL, NULL, NULL },
        { "updatedn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
@@ -598,7 +611,7 @@ static ConfigOCs cf_ocs[] = {
                "MAY ( cn $ olcConfigFile $ olcConfigDir $ olcAllows $ olcArgsFile $ "
                 "olcAttributeOptions $ olcAuthIDRewrite $ "
                 "olcAuthzPolicy $ olcAuthzRegexp $ olcConcurrency $ "
-                "olcConnMaxPending $ olcConnMaxPendingAuth $ olcDefaultSearchBase $ "
+                "olcConnMaxPending $ olcConnMaxPendingAuth $ "
                 "olcDisallows $ olcGentleHUP $ olcIdleTimeout $ "
                 "olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ "
                 "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcLocalSSF $ "
@@ -614,7 +627,7 @@ static ConfigOCs cf_ocs[] = {
                 "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
                 "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
                 "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
-                "olcTLSRandFile $ olcTLSVerifyClient $ "
+                "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamDir $ "
                 "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
                 "olcDitContentRules ) )", Cft_Global },
        { "( OLcfgGlOc:2 "
@@ -634,7 +647,7 @@ static ConfigOCs cf_ocs[] = {
                "DESC 'OpenLDAP Database-specific options' "
                "SUP olcConfig STRUCTURAL "
                "MUST olcDatabase "
-               "MAY ( olcSuffix $ olcAccess $ olcLastMod $ olcLimits $ "
+               "MAY ( olcSuffix $ olcSubordinate $ olcAccess $ olcLastMod $ olcLimits $ "
                 "olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
                 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
                 "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
@@ -1375,7 +1388,7 @@ config_passwd_hash(ConfigArgs *c) {
        }
        for(i = 1; i < c->argc; i++) {
                if(!lutil_passwd_scheme(c->argv[i])) {
-                       sprintf( c->msg, "<%s> schema not available", c->argv[0] );
+                       sprintf( c->msg, "<%s> scheme not available", c->argv[0] );
                        Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
                                c->log, c->msg, c->argv[i]);
                } else {
@@ -1560,6 +1573,42 @@ config_overlay(ConfigArgs *c) {
        return(0);
 }
 
+static int
+config_subordinate(ConfigArgs *c)
+{
+       int rc = 1;
+       int advertise;
+
+       switch( c->op ) {
+       case SLAP_CONFIG_EMIT:
+               if ( SLAP_GLUE_SUBORDINATE( c->be )) {
+                       struct berval bv;
+
+                       bv.bv_val = SLAP_GLUE_ADVERTISE( c->be ) ? "advertise" : "TRUE";
+                       bv.bv_len = SLAP_GLUE_ADVERTISE( c->be ) ? STRLENOF("advertise") :
+                               STRLENOF("TRUE");
+
+                       value_add_one( &c->rvalue_vals, &bv );
+                       rc = 0;
+               }
+               break;
+       case LDAP_MOD_DELETE:
+               if ( !c->line  || strcasecmp( c->line, "advertise" )) {
+                       glue_sub_del( c->be );
+               } else {
+                       SLAP_DBFLAGS( c->be ) &= ~SLAP_DBFLAG_GLUE_ADVERTISE;
+               }
+               rc = 0;
+               break;
+       case LDAP_MOD_ADD:
+       case SLAP_CONFIG_ADD:
+               advertise = ( c->argc == 2 && !strcasecmp( c->argv[1], "advertise" ));
+               rc = glue_sub_add( c->be, advertise, CONFIG_ONLINE_ADD( c ));
+               break;
+       }
+       return rc;
+}
+
 static int
 config_suffix(ConfigArgs *c)
 {
@@ -1663,8 +1712,16 @@ config_suffix(ConfigArgs *c)
                free(pdn.bv_val);
                free(ndn.bv_val);
        } else if(tbe) {
-               sprintf( c->msg, "<%s> suffix already served by a preceding backend",
-                       c->argv[0] );
+               char    *type = tbe->bd_info->bi_type;
+
+               if ( overlay_is_over( tbe ) ) {
+                       slap_overinfo   *oi = (slap_overinfo *)tbe->bd_info->bi_private;
+                       type = oi->oi_orig->bi_type;
+               }
+
+               sprintf( c->msg, "<%s> namingContext \"%s\" already served by "
+                       "a preceding %s database serving namingContext",
+                       c->argv[0], pdn.bv_val, type );
                Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                        c->log, c->msg, tbe->be_suffix[0].bv_val);
                free(pdn.bv_val);
@@ -1945,6 +2002,60 @@ slap_loglevel_register( slap_mask_t m, struct berval *s )
        return rc;
 }
 
+int
+str2loglevel( const char *s, int *l )
+{
+       int     i;
+
+       if ( loglevel_ops == NULL ) {
+               loglevel_init();
+       }
+
+       i = verb_to_mask( s, loglevel_ops );
+
+       if ( BER_BVISNULL( &loglevel_ops[ i ].word) ) {
+               return -1;
+       }
+
+       *l = loglevel_ops[ i ].mask;
+
+       return 0;
+}
+
+const char *
+loglevel2str( int l )
+{
+       struct berval   bv = BER_BVNULL;
+
+       loglevel2bv( l, &bv );
+
+       return bv.bv_val;
+}
+
+int
+loglevel2bv( int l, struct berval *bv )
+{
+       if ( loglevel_ops == NULL ) {
+               loglevel_init();
+       }
+
+       BER_BVZERO( bv );
+
+       return enum_to_verb( loglevel_ops, l, bv ) == -1;
+}
+
+int
+loglevel2bvarray( int l, BerVarray *bva )
+{
+       if ( loglevel_ops == NULL ) {
+               loglevel_init();
+       }
+
+       return mask_to_verbs( loglevel_ops, l, bva );
+}
+
+static int config_syslog;
+
 static int
 config_loglevel(ConfigArgs *c) {
        int i;
@@ -1955,18 +2066,25 @@ config_loglevel(ConfigArgs *c) {
        }
 
        if (c->op == SLAP_CONFIG_EMIT) {
-               return mask_to_verbs( loglevel_ops, ldap_syslog, &c->rvalue_vals );
+               /* Get default or commandline slapd setting */
+               if ( ldap_syslog && !config_syslog )
+                       config_syslog = ldap_syslog;
+               return loglevel2bvarray( config_syslog, &c->rvalue_vals );
+
        } else if ( c->op == LDAP_MOD_DELETE ) {
                if ( !c->line ) {
-                       ldap_syslog = 0;
+                       config_syslog = 0;
                } else {
                        int level = verb_to_mask( c->line, loglevel_ops );
-                       ldap_syslog ^= level;
+                       config_syslog ^= level;
+               }
+               if ( slapMode & SLAP_SERVER_MODE ) {
+                       ldap_syslog = config_syslog;
                }
                return 0;
        }
 
-       ldap_syslog = 0;
+       config_syslog = 0;
 
        for( i=1; i < c->argc; i++ ) {
                int     level;
@@ -1980,16 +2098,17 @@ config_loglevel(ConfigArgs *c) {
                                return( 1 );
                        }
                } else {
-                       int j = verb_to_mask(c->argv[i], loglevel_ops);
-                       if(BER_BVISNULL(&loglevel_ops[j].word)) {
+                       if ( str2loglevel( c->argv[i], &level ) ) {
                                sprintf( c->msg, "<%s> unknown level", c->argv[0] );
                                Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                        c->log, c->msg, c->argv[i]);
                                return( 1 );
                        }
-                       level = loglevel_ops[j].mask;
                }
-               ldap_syslog |= level;
+               config_syslog |= level;
+       }
+       if ( slapMode & SLAP_SERVER_MODE ) {
+               ldap_syslog = config_syslog;
        }
        return(0);
 }
@@ -2207,6 +2326,7 @@ config_replica(ConfigArgs *c) {
                                return(1);
                        }
                        if(!ludp->lud_host) {
+                               ldap_free_urldesc(ludp);
                                sprintf( c->msg, "<%s> invalid uri - missing hostname",
                                        c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
@@ -2280,8 +2400,6 @@ config_replica(ConfigArgs *c) {
 
 static int
 config_updatedn(ConfigArgs *c) {
-       struct berval dn;
-       int rc;
        if (c->op == SLAP_CONFIG_EMIT) {
                if (!BER_BVISEMPTY(&c->be->be_update_ndn)) {
                        value_add_one(&c->rvalue_vals, &c->be->be_update_ndn);
@@ -2291,7 +2409,7 @@ config_updatedn(ConfigArgs *c) {
                return 1;
        } else if ( c->op == LDAP_MOD_DELETE ) {
                ch_free( c->be->be_update_ndn.bv_val );
-               c->be->be_update_ndn.bv_val = NULL;
+               BER_BVZERO( &c->be->be_update_ndn );
                SLAP_DBFLAGS(c->be) ^= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SLURP_SHADOW);
                return 0;
        }
@@ -2302,17 +2420,13 @@ config_updatedn(ConfigArgs *c) {
                return(1);
        }
 
-       ber_str2bv(c->argv[1], 0, 0, &dn);
-
-       rc = dnNormalize(0, NULL, NULL, &dn, &c->be->be_update_ndn, NULL);
-
-       if(rc != LDAP_SUCCESS) {
-               sprintf( c->msg, "<%s> invalid DN %d (%s)", c->argv[0],
-                       rc, ldap_err2string(rc));
-               Debug(LDAP_DEBUG_ANY, "%s: %s\n",
-                       c->log, c->msg, 0 );
-               return(1);
+       ber_memfree_x( c->value_dn.bv_val, NULL );
+       if ( !BER_BVISNULL( &c->be->be_update_ndn ) ) {
+               ber_memfree_x( c->be->be_update_ndn.bv_val, NULL );
        }
+       c->be->be_update_ndn = c->value_ndn;
+       BER_BVZERO( &c->value_dn );
+       BER_BVZERO( &c->value_ndn );
 
        SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SLURP_SHADOW);
        return(0);
@@ -2409,6 +2523,7 @@ config_tls_option(ConfigArgs *c) {
        case CFG_TLS_CERT_KEY:  flag = LDAP_OPT_X_TLS_KEYFILE;          break;
        case CFG_TLS_CA_PATH:   flag = LDAP_OPT_X_TLS_CACERTDIR;        break;
        case CFG_TLS_CA_FILE:   flag = LDAP_OPT_X_TLS_CACERTFILE;       break;
+       case CFG_TLS_DH_DIR:    flag = LDAP_OPT_X_TLS_DHPARAMDIR;       break;
        default:                Debug(LDAP_DEBUG_ANY, "%s: "
                                        "unknown tls_option <0x%x>\n",
                                        c->log, c->type, 0);
@@ -2522,6 +2637,10 @@ config_ldif_resp( Operation *op, SlapReply *rs )
 
                sc->cfb->cb_got_ldif = 1;
                rs->sr_err = config_add_internal( sc->cfb, rs->sr_entry, sc->ca, NULL, NULL );
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_ANY, "config error processing %s: %s\n",
+                               rs->sr_entry->e_name.bv_val, sc->ca->msg, 0 );
+               }
        }
        return rs->sr_err;
 }
@@ -2537,7 +2656,7 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
        setup_cookie sc;
        slap_callback cb = { NULL, config_ldif_resp, NULL, NULL };
        Connection conn = {0};
-       char opbuf[OPERATION_BUFFER_SIZE];
+       OperationBuffer opbuf;
        Operation *op;
        SlapReply rs = {REP_RESULT};
        Filter filter = { LDAP_FILTER_PRESENT };
@@ -2587,8 +2706,10 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
                return 1;
 
        if ( readit ) {
-               op = (Operation *)opbuf;
-               connection_fake_init( &conn, op, cfb );
+               void *thrctx = ldap_pvt_thread_pool_context();
+
+               op = (Operation *) &opbuf;
+               connection_fake_init( &conn, op, thrctx );
 
                filter.f_desc = slap_schema.si_ad_objectClass;
 
@@ -2618,7 +2739,7 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
                op->o_bd = &cfb->cb_db;
                rc = op->o_bd->be_search( op, &rs );
 
-               slap_sl_mem_destroy( NULL, op->o_tmpmemctx );
+               ldap_pvt_thread_pool_context_reset( thrctx );
        }
 
        cfb->cb_use_ldif = 1;
@@ -2879,8 +3000,11 @@ check_vals( ConfigTable *ct, ConfigArgs *ca, void *ptr, int isAttr )
        if ( a && ( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL )) {
                sort = 1;
                rc = ordered_value_sort( a, 1 );
-               if ( rc )
+               if ( rc ) {
+                       sprintf(ca->msg, "ordered_value_sort failed on attr %s\n",
+                               ad->ad_cname.bv_val );
                        return rc;
+               }
        }
        for ( i=0; vals[i].bv_val; i++ ) {
                ca->line = vals[i].bv_val;
@@ -3201,7 +3325,7 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, i
        }
 
        if ( rc != LDAP_SUCCESS )
-               goto leave;
+               goto done;
 
        /* Parse all the values and check for simple syntax errors before
         * performing any set actions.
@@ -3221,7 +3345,7 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, i
         */
        rc = check_name_index( last, colst[0]->co_type, e, rs, renum );
        if ( rc )
-               goto leave;
+               goto done;
 
        init_config_argv( ca );
 
@@ -3233,7 +3357,7 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, i
                ct = config_find_table( colst, nocs, a->a_desc );
                if ( !ct ) continue;    /* user data? */
                rc = check_vals( ct, ca, a, 1 );
-               if ( rc ) goto leave;
+               if ( rc ) goto done;
        }
 
        /* Basic syntax checks are OK. Do the actual settings. */
@@ -3251,7 +3375,7 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs, i
                        rc = config_parse_add( ct, ca );
                        if ( rc ) {
                                rc = LDAP_OTHER;
-                               goto leave;
+                               goto done;
                        }
                }
        }
@@ -3274,7 +3398,7 @@ ok:
                        Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
                                ca->log, ca->msg, ca->argv[1] );
                        rc = LDAP_OTHER;
-                       goto leave;
+                       goto done;
                }
        }
 
@@ -3298,7 +3422,7 @@ ok:
                last->ce_kids = ce;
        }
 
-leave:
+done:
        if ( rc ) {
                if ( (colst[0]->co_type == Cft_Database) && ca->be ) {
                        if ( ca->be != frontendDB )
@@ -3346,6 +3470,11 @@ config_back_add( Operation *op, SlapReply *rs )
                BackendDB *be = op->o_bd;
                slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
                op->o_bd = &cfb->cb_db;
+               /* FIXME: there must be a better way. */
+               if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) {
+                       op->o_bd->be_rootdn = be->be_rootdn;
+                       op->o_bd->be_rootndn= be->be_rootndn;
+               }
                sc.sc_next = op->o_callback;
                op->o_callback = &sc;
                op->o_bd->be_add( op, rs );
@@ -3670,6 +3799,10 @@ config_back_modify( Operation *op, SlapReply *rs )
                BackendDB *be = op->o_bd;
                slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
                op->o_bd = &cfb->cb_db;
+               if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) {
+                       op->o_bd->be_rootdn = be->be_rootdn;
+                       op->o_bd->be_rootndn= be->be_rootndn;
+               }
                sc.sc_next = op->o_callback;
                op->o_callback = &sc;
                op->o_bd->be_modify( op, rs );
@@ -3963,18 +4096,20 @@ config_back_db_open( BackendDB *be )
        BackendInfo *bi;
        ConfigArgs c;
        Connection conn = {0};
-       char opbuf[OPERATION_BUFFER_SIZE];
+       OperationBuffer opbuf;
        Operation *op;
        slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
        SlapReply rs = {REP_RESULT};
+       void *thrctx = NULL;
 
        /* If we read the config from back-ldif, nothing to do here */
        if ( cfb->cb_got_ldif )
                return 0;
 
        if ( cfb->cb_use_ldif ) {
-               op = (Operation *)opbuf;
-               connection_fake_init( &conn, op, cfb );
+               thrctx = ldap_pvt_thread_pool_context();
+               op = (Operation *) &opbuf;
+               connection_fake_init( &conn, op, thrctx );
 
                op->o_dn = be->be_rootdn;
                op->o_ndn = be->be_rootndn;
@@ -4085,8 +4220,8 @@ config_back_db_open( BackendDB *be )
                        }
                }
        }
-       if ( op )
-               slap_sl_mem_destroy( NULL, op->o_tmpmemctx );
+       if ( thrctx )
+               ldap_pvt_thread_pool_context_reset( thrctx );
 
        return 0;
 }