]> git.sur5r.net Git - openldap/commitdiff
More back-config / back-ldif integration, added config_generic_wrapper,
authorHoward Chu <hyc@openldap.org>
Tue, 15 Mar 2005 08:57:34 +0000 (08:57 +0000)
committerHoward Chu <hyc@openldap.org>
Tue, 15 Mar 2005 08:57:34 +0000 (08:57 +0000)
added -F option to specify config directory

servers/slapd/back-bdb/config.c
servers/slapd/back-bdb/init.c
servers/slapd/back-ldif/ldif.c
servers/slapd/bconfig.c
servers/slapd/config.c
servers/slapd/config.h
servers/slapd/main.c
servers/slapd/proto-slap.h
servers/slapd/slapcommon.c

index a6d4d28e68df2ced04eefe1b7c439dfaf531acbb..84bfb5e72491255b1891796ffcd1e4cf8f9d7732 100644 (file)
@@ -122,7 +122,7 @@ static ConfigOCs bdbocs[] = {
 static int
 bdb_cf_oc(ConfigArgs *c)
 {
-       if ( c->emit ) {
+       if ( c->op == SLAP_CONFIG_EMIT ) {
                value_add_one( &c->rvalue_vals, &bdb_oc->soc_cname );
                return 0;
        }
@@ -144,7 +144,7 @@ bdb_cf_gen(ConfigArgs *c)
        struct bdb_info *bdb = c->be->be_private;
        int rc;
 
-       if ( c->emit ) {
+       if ( c->op == SLAP_CONFIG_EMIT ) {
                rc = 0;
                switch( c->type ) {
                case BDB_CHKPT:
@@ -246,22 +246,3 @@ int bdb_back_init_cf( BackendInfo *bi )
        rc = init_config_ocs( bdbocs );
        return rc;
 }
-
-int bdb_db_config( Backend *be, const char *fname, int lineno, int argc,
-       char **argv )
-{
-       ConfigArgs c = { 0 };
-       int rc;
-
-       c.be = be;
-       c.fname = fname;
-       c.lineno = lineno;
-       c.argc = argc;
-       c.argv = argv;
-       sprintf( c.log, "%s: line %lu", fname, lineno );
-
-       rc = parse_config_table( bdbcfg, &c );
-       if ( rc == ARG_UNKNOWN )
-               rc = SLAP_CONF_UNKNOWN;
-       return rc;
-}
index 8893333fc356506a22ca6e0aef3637ba98839bc1..e202de4cfcfb137bc65309a3076991919621b8be 100644 (file)
@@ -536,7 +536,7 @@ bdb_back_initialize(
        bi->bi_destroy = 0;
 
        bi->bi_db_init = bdb_db_init;
-       bi->bi_db_config = bdb_db_config;
+       bi->bi_db_config = config_generic_wrapper;
        bi->bi_db_open = bdb_db_open;
        bi->bi_db_close = bdb_db_close;
        bi->bi_db_destroy = bdb_db_destroy;
index 56f147489df995a5ed1113e262a703381bcac143..4756b4a9d2e129c84b9ef24ab32d80693c8a4b0f 100644 (file)
@@ -29,6 +29,7 @@
 #include <ac/unistd.h>
 #include "slap.h"
 #include "lutil.h"
+#include "config.h"
 
 struct ldif_info {
        struct berval li_base_path;
@@ -43,6 +44,43 @@ struct ldif_info {
 
 #define ENTRY_BUFF_INCREMENT 500
 
+static ObjectClass *ldif_oc;
+
+static ConfigDriver ldif_cf;
+
+static ConfigTable ldifcfg[] = {
+       { "", "", 0, 0, 0, ARG_MAGIC,
+               ldif_cf, NULL, NULL, NULL },
+       { "directory", "dir", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+               (void *)offsetof(struct ldif_info, li_base_path),
+               "( OLcfgAt:1.1 NAME 'dbDirectory' "
+                       "DESC 'Directory for database content' "
+                       "EQUALITY caseIgnoreMatch "
+                       "SYNTAX OMsDirectoryString )", NULL, NULL },
+       { NULL, NULL, 0, 0, 0, ARG_IGNORED,
+               NULL, NULL, NULL, NULL }
+};
+
+static ConfigOCs ldifocs[] = {
+       { "( OLcfgOc:2.1 "
+               "NAME 'ldifConfig' "
+               "DESC 'LDIF backend configuration' "
+               "AUXILIARY "
+               "MAY ( dbDirectory ) )",
+               &ldif_oc },
+       { NULL, NULL }
+};
+
+static int
+ldif_cf( ConfigArgs *c )
+{
+       if ( c->op == SLAP_CONFIG_EMIT ) {
+               value_add_one( &c->rvalue_vals, &ldif_oc->soc_cname );
+               return 0;
+       }
+       return 1;
+}
+
 static char *
 dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path)
 {
@@ -552,7 +590,7 @@ static int ldif_back_modify(Operation *op, SlapReply *rs) {
          SLAP_FREE(path);
        if(entry != NULL)
          entry_free(entry);
-       rs->sr_text = "";
+       rs->sr_text = NULL;
        ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
        ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
        send_ldap_result(op, rs);
@@ -883,31 +921,6 @@ static ID ldif_tool_entry_put(BackendDB * be, Entry * e, struct berval *text) {
          return NOID;
 }
 
-static int
-ldif_back_db_config(
-                   BackendDB   *be,
-                   const char  *fname,
-                   int                 lineno,
-                   int                 argc,
-                   char                **argv )
-{
-       struct ldif_info *ni = (struct ldif_info *) be->be_private;
-
-       if ( strcasecmp( argv[0], "directory" ) == 0 ) {
-         if ( argc < 2 ) {
-           fprintf( stderr,
-              "%s: line %d: missing <path> in \"directory <path>\" line\n",
-              fname, lineno );
-           return 1;
-         }
-         ber_str2bv(argv[1], 0, 1, &ni->li_base_path);
-       } else {
-         return SLAP_CONF_UNKNOWN;
-       }
-       return 0;
-}
-
-
 static int
 ldif_back_db_init( BackendDB *be )
 {
@@ -915,6 +928,7 @@ ldif_back_db_init( BackendDB *be )
 
        ni = ch_calloc( 1, sizeof(struct ldif_info) );
        be->be_private = ni;
+       be->be_cf_table = be->bd_info->bi_cf_table;
        ldap_pvt_thread_mutex_init(&ni->li_mutex);
        return 0;
 }
@@ -948,13 +962,17 @@ ldif_back_initialize(
                     BackendInfo        *bi
                     )
 {
+       int rc;
+
+       bi->bi_cf_table = ldifcfg;
+
        bi->bi_open = 0;
        bi->bi_close = 0;
        bi->bi_config = 0;
        bi->bi_destroy = 0;
 
        bi->bi_db_init = ldif_back_db_init;
-       bi->bi_db_config = ldif_back_db_config;
+       bi->bi_db_config = config_generic_wrapper;
        bi->bi_db_open = ldif_back_db_open;
        bi->bi_db_close = 0;
        bi->bi_db_destroy = ldif_back_db_destroy;
@@ -989,5 +1007,9 @@ ldif_back_initialize(
        bi->bi_tool_id2entry_get = 0;
        bi->bi_tool_entry_modify = 0;
 
-       return 0;
+       rc = init_config_attrs( ldifcfg );
+       if ( rc ) return rc;
+       ldifcfg[0].ad = slap_schema.si_ad_objectClass;
+       rc = init_config_ocs( ldifocs );
+       return rc;
 }
index 577b3309535737e5d79c921514957bc92f980c09..ae499a5ec5406bdc94e68bf26654385447c3365c 100644 (file)
@@ -68,6 +68,8 @@ typedef struct CfEntryInfo {
 typedef struct {
        ConfigFile *cb_config;
        CfEntryInfo *cb_root;
+       BackendDB       cb_db;  /* underlying database */
+       int             cb_got_ldif;
 } CfBackInfo;
 
 /* These do nothing in slapd, they're kept only to make them
@@ -80,6 +82,8 @@ static char   *passwd_salt;
 static char    *logfileName;
 static BerVarray authz_rewrites;
 
+static struct berval cfdir;
+
 static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
        *cfAd_include;
 
@@ -93,6 +97,7 @@ static int parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *));
 static void syncrepl_unparse LDAP_P (( syncinfo_t *, struct berval *));
 
 static ConfigDriver config_fname;
+static ConfigDriver config_cfdir;
 static ConfigDriver config_generic;
 static ConfigDriver config_search_base;
 static ConfigDriver config_passwd_hash;
@@ -191,6 +196,11 @@ ConfigTable config_back_cf_table[] = {
                        "DESC 'File for slapd configuration directives' "
                        "EQUALITY caseIgnoreMatch "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "", "", 0, 0, 0, ARG_MAGIC,
+               &config_cfdir, "( OLcfgAt:79 NAME 'olcConfigDir' "
+                       "DESC 'Directory for slapd configuration backend' "
+                       "EQUALITY caseIgnoreMatch "
+                       "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
        { "access",     NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|CFG_ACL,
                &config_generic, "( OLcfgAt:1 NAME 'olcAccess' "
                        "DESC 'Access Control List' "
@@ -238,10 +248,10 @@ ConfigTable config_back_cf_table[] = {
        { "concurrency", "level", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_CONCUR,
                &config_generic, "( OLcfgAt:10 NAME 'olcConcurrency' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "conn_max_pending", "max", 2, 2, 0, ARG_LONG,
+       { "conn_max_pending", "max", 2, 2, 0, ARG_INT,
                &slap_conn_max_pending, "( OLcfgAt:11 NAME 'olcConnMaxPending' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "conn_max_pending_auth", "max", 2, 2, 0, ARG_LONG,
+       { "conn_max_pending_auth", "max", 2, 2, 0, ARG_INT,
                &slap_conn_max_pending_auth, "( OLcfgAt:12 NAME 'olcConnMaxPendingAuth' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "database", "type", 2, 2, 0, ARG_MAGIC|CFG_DATABASE,
@@ -291,7 +301,7 @@ ConfigTable config_back_cf_table[] = {
        { "limits", "limits", 2, 0, 0, ARG_DB|ARG_MAGIC|CFG_LIMITS,
                &config_generic, "( OLcfgAt:25 NAME 'olcLimits' "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "localSSF", "ssf", 2, 2, 0, ARG_LONG,
+       { "localSSF", "ssf", 2, 2, 0, ARG_INT,
                &local_ssf, "( OLcfgAt:26 NAME 'olcLocalSSF' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "logfile", "file", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_LOGFILE,
@@ -439,10 +449,10 @@ ConfigTable config_back_cf_table[] = {
        { "sizelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC|CFG_SIZE,
                &config_sizelimit, "( OLcfgAt:60 NAME 'olcSizeLimit' "
                        "SYNTAX OMsInteger )", NULL, NULL },
-       { "sockbuf_max_incoming", "max", 2, 2, 0, ARG_LONG,
+       { "sockbuf_max_incoming", "max", 2, 2, 0, ARG_BER_LEN_T,
                &sockbuf_max_incoming, "( OLcfgAt:61 NAME 'olcSockbufMaxIncoming' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "sockbuf_max_incoming_auth", "max", 2, 2, 0, ARG_LONG,
+       { "sockbuf_max_incoming_auth", "max", 2, 2, 0, ARG_BER_LEN_T,
                &sockbuf_max_incoming_auth, "( OLcfgAt:62 NAME 'olcSockbufMaxIncomingAuth' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "srvtab", "file", 2, 2, 0,
@@ -551,7 +561,7 @@ static ConfigOCs cf_ocs[] = {
                "NAME 'olcGlobal' "
                "DESC 'OpenLDAP Global configuration options' "
                "SUP olcConfig STRUCTURAL "
-               "MAY ( olcAllows $ olcArgsFile $ olcAttributeOptions $ "
+               "MAY ( olcConfigDir $ olcAllows $ olcArgsFile $ olcAttributeOptions $ "
                 "olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ "
                 "olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ "
                 "olcDefaultSearchBase $ olcDisallows $ olcGentleHUP $ "
@@ -607,7 +617,7 @@ config_generic(ConfigArgs *c) {
        char *p;
        int i;
 
-       if ( c->emit ) {
+       if ( c->op == SLAP_CONFIG_EMIT ) {
                int rc = 0;
                switch(c->type) {
                case CFG_CONCUR:
@@ -1038,7 +1048,7 @@ config_generic(ConfigArgs *c) {
 
 static int
 config_fname(ConfigArgs *c) {
-       if(c->emit && c->line) {
+       if(c->op == SLAP_CONFIG_EMIT && c->line) {
                ConfigFile *cf = (ConfigFile *)c->line;
                value_add_one( &c->rvalue_vals, &cf->c_file );
                return 0;
@@ -1046,11 +1056,20 @@ config_fname(ConfigArgs *c) {
        return(1);
 }
 
+static int
+config_cfdir(ConfigArgs *c) {
+       if(c->op == SLAP_CONFIG_EMIT) {
+               value_add_one( &c->rvalue_vals, &cfdir );
+               return 0;
+       }
+       return(1);
+}
+
 static int
 config_search_base(ConfigArgs *c) {
        struct berval dn;
 
-       if(c->emit) {
+       if(c->op == SLAP_CONFIG_EMIT) {
                int rc = 1;
                if (!BER_BVISEMPTY(&default_search_base)) {
                        value_add_one(&c->rvalue_vals, &default_search_base);
@@ -1084,7 +1103,7 @@ config_search_base(ConfigArgs *c) {
 static int
 config_passwd_hash(ConfigArgs *c) {
        int i;
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                struct berval bv;
                for (i=0; default_passwd_hash && default_passwd_hash[i]; i++) {
                        ber_str2bv(default_passwd_hash[i], 0, 0, &bv);
@@ -1117,12 +1136,14 @@ config_passwd_hash(ConfigArgs *c) {
 
 static int
 config_schema_dn(ConfigArgs *c) {
-       struct berval dn;
-       int rc;
-       if ( c->emit ) {
-               value_add_one(&c->rvalue_vals, &c->be->be_schemadn);
-               value_add_one(&c->rvalue_nvals, &c->be->be_schemandn);
-               return 0;
+       if ( c->op == SLAP_CONFIG_EMIT ) {
+               int rc = 1;
+               if ( !BER_BVISEMPTY( &c->be->be_schemadn )) {
+                       value_add_one(&c->rvalue_vals, &c->be->be_schemadn);
+                       value_add_one(&c->rvalue_nvals, &c->be->be_schemandn);
+                       rc = 0;
+               }
+               return rc;
        }
        c->be->be_schemadn = c->value_dn;
        c->be->be_schemandn = c->value_ndn;
@@ -1134,7 +1155,7 @@ config_sizelimit(ConfigArgs *c) {
        int i, rc = 0;
        char *next;
        struct slap_limits_set *lim = &c->be->be_def_limit;
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                char buf[8192];
                struct berval bv;
                bv.bv_val = buf;
@@ -1182,7 +1203,7 @@ config_timelimit(ConfigArgs *c) {
        int i, rc = 0;
        char *next;
        struct slap_limits_set *lim = &c->be->be_def_limit;
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                char buf[8192];
                struct berval bv;
                bv.bv_val = buf;
@@ -1227,7 +1248,7 @@ config_timelimit(ConfigArgs *c) {
 
 static int
 config_overlay(ConfigArgs *c) {
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return 1;
        }
        if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1])) {
@@ -1245,7 +1266,7 @@ config_suffix(ConfigArgs *c) {
        Backend *tbe;
        struct berval pdn, ndn;
        int rc;
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                if ( !BER_BVISNULL( &c->be->be_suffix[0] )) {
                        value_add( &c->rvalue_vals, c->be->be_suffix );
                        value_add( &c->rvalue_nvals, c->be->be_nsuffix );
@@ -1289,7 +1310,7 @@ config_suffix(ConfigArgs *c) {
 
 static int
 config_rootdn(ConfigArgs *c) {
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                if ( !BER_BVISNULL( &c->be->be_rootdn )) {
                        value_add_one(&c->rvalue_vals, &c->be->be_rootdn);
                        value_add_one(&c->rvalue_nvals, &c->be->be_rootndn);
@@ -1306,7 +1327,7 @@ config_rootdn(ConfigArgs *c) {
 static int
 config_rootpw(ConfigArgs *c) {
        Backend *tbe;
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                if (!BER_BVISEMPTY(&c->be->be_rootpw)) {
                        c->value_string=ch_strdup("*");
                        return 0;
@@ -1348,7 +1369,7 @@ config_restrict(ConfigArgs *c) {
                { BER_BVNULL,   0 }
        };
 
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return mask_to_verbs( restrictable_ops, c->be->be_restrictops,
                        &c->rvalue_vals );
        }
@@ -1376,7 +1397,7 @@ config_allows(ConfigArgs *c) {
                { BER_BVC("update_anon"),       SLAP_ALLOW_UPDATE_ANON },
                { BER_BVNULL,   0 }
        };
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return mask_to_verbs( allowable_ops, global_allows, &c->rvalue_vals );
        }
        i = verbs_to_mask(c->argc, c->argv, allowable_ops, &allows);
@@ -1402,7 +1423,7 @@ config_disallows(ConfigArgs *c) {
                { BER_BVC("tls_authc"),         SLAP_DISALLOW_TLS_AUTHC },
                { BER_BVNULL, 0 }
        };
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return mask_to_verbs( disallowable_ops, global_disallows, &c->rvalue_vals );
        }
        i = verbs_to_mask(c->argc, c->argv, disallowable_ops, &disallows);
@@ -1428,7 +1449,7 @@ config_requires(ConfigArgs *c) {
                { BER_BVC("strong"),            SLAP_REQUIRE_STRONG },
                { BER_BVNULL, 0 }
        };
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return mask_to_verbs( requires_ops, c->be->be_requires, &c->rvalue_vals );
        }
        i = verbs_to_mask(c->argc, c->argv, requires_ops, &requires);
@@ -1465,7 +1486,7 @@ config_loglevel(ConfigArgs *c) {
                { BER_BVNULL,   0 }
        };
 
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return mask_to_verbs( loglevel_ops, ldap_syslog, &c->rvalue_vals );
        }
 
@@ -1501,7 +1522,7 @@ config_loglevel(ConfigArgs *c) {
 
 static int
 config_syncrepl(ConfigArgs *c) {
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                if ( c->be->be_syncinfo ) {
                        struct berval bv;
                        syncrepl_unparse( c->be->be_syncinfo, &bv ); 
@@ -1525,7 +1546,7 @@ config_syncrepl(ConfigArgs *c) {
 static int
 config_referral(ConfigArgs *c) {
        struct berval vals[2];
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                if ( default_referral ) {
                        value_add( &c->rvalue_vals, default_referral );
                        return 0;
@@ -1567,7 +1588,7 @@ config_security(ConfigArgs *c) {
        slap_ssf_set_t *set = &c->be->be_ssf_set;
        char *next;
        int i, j;
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                char numbuf[32];
                struct berval bv;
                slap_ssf_t *tgt;
@@ -1686,7 +1707,7 @@ config_replica(ConfigArgs *c) {
        char *replicahost, *replicauri;
        LDAPURLDesc *ludp;
 
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                if (c->be->be_replica) {
                        struct berval bv;
                        for (i=0;c->be->be_replica[i]; i++) {
@@ -1791,7 +1812,7 @@ static int
 config_updatedn(ConfigArgs *c) {
        struct berval dn;
        int rc;
-       if (c->emit) {
+       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);
                        value_add_one(&c->rvalue_nvals, &c->be->be_update_ndn);
@@ -1824,7 +1845,7 @@ config_updatedn(ConfigArgs *c) {
 static int
 config_updateref(ConfigArgs *c) {
        struct berval vals[2];
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                if ( c->be->be_update_refs ) {
                        value_add( &c->rvalue_vals, c->be->be_update_refs );
                        return 0;
@@ -1858,7 +1879,7 @@ config_include(ConfigArgs *c) {
        ConfigFile *cf;
        ConfigFile *cfsave = cfn;
        ConfigFile *cf2 = NULL;
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return 1;
        }
        cf = ch_calloc( 1, sizeof(ConfigFile));
@@ -1900,7 +1921,7 @@ config_tls_option(ConfigArgs *c) {
                                        "unknown tls_option <%x>\n",
                                        c->log, c->type, 0);
        }
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                return ldap_pvt_tls_get_option( NULL, flag, &c->value_string );
        }
        ch_free(c->value_string);
@@ -1935,7 +1956,7 @@ config_tls_config(ConfigArgs *c) {
                                        "unknown tls_option <%x>\n",
                                        c->log, c->type, 0);
        }
-       if (c->emit) {
+       if (c->op == SLAP_CONFIG_EMIT) {
                ldap_pvt_tls_get_option( NULL, flag, &c->value_int );
                for (i=0; !BER_BVISNULL(&keys[i].word); i++) {
                        if (keys[i].mask == c->value_int) {
@@ -2471,32 +2492,6 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
        ber_dupbv( bv, &bc );
 }
 
-
-int
-read_config(const char *fname, int depth) {
-
-       if ( !backend_db_init( "config" ))
-               return 1;
-
-       ber_str2bv( fname, 0, 1, &cf_prv.c_file );
-       return read_config_file(fname, depth, NULL);
-}
-
-static int
-config_back_bind( Operation *op, SlapReply *rs )
-{
-       if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
-               ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
-               /* frontend sends result */
-               return LDAP_SUCCESS;
-       }
-
-       rs->sr_err = LDAP_INVALID_CREDENTIALS;
-       send_ldap_result( op, rs );
-
-       return rs->sr_err;
-}
-
 static CfEntryInfo *
 config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last )
 {
@@ -2531,6 +2526,149 @@ config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last )
        return root;
 }
 
+static int
+config_ldif_resp( Operation *op, SlapReply *rs )
+{
+       if ( rs->sr_type == REP_SEARCH ) {
+               CfBackInfo *cfb = op->o_callback->sc_private;
+               CfEntryInfo *ce, *last;
+
+               cfb->cb_got_ldif = 1;
+               config_find_base( cfb->cb_root, &rs->sr_entry->e_nname, &last );
+               ce = ch_calloc( 1, sizeof(CfEntryInfo) );
+               ce->ce_entry = entry_dup( rs->sr_entry );
+               ce->ce_entry->e_private = ce;
+               if ( !last ) {
+                       cfb->cb_root = ce;
+               } else if ( last->ce_kids ) {
+                       CfEntryInfo *c2;
+
+                       for (c2=last->ce_kids; c2 && c2->ce_sibs; c2 = c2->ce_sibs);
+                       c2->ce_sibs = ce;
+               } else {
+                       last->ce_kids = ce;
+               }
+       }
+       return 0;
+}
+
+/* Configure and read the underlying back-ldif store */
+static int
+config_setup_ldif( BackendDB *be, const char *dir ) {
+       CfBackInfo *cfb = be->be_private;
+       ConfigArgs c = {0};
+       ConfigTable *ct;
+       char *argv[3];
+       int rc;
+       slap_callback cb = { NULL, config_ldif_resp, NULL, NULL };
+       Connection conn = {0};
+       char opbuf[OPERATION_BUFFER_SIZE];
+       Operation *op;
+       SlapReply rs = {REP_RESULT};
+       Filter filter = { LDAP_FILTER_PRESENT };
+       struct berval filterstr = BER_BVC("(objectclass=*)");
+
+       cfb->cb_db.bd_info = backend_info( "ldif" );
+       if ( !cfb->cb_db.bd_info )
+               return 1;
+
+       if ( cfb->cb_db.bd_info->bi_db_init( &cfb->cb_db )) return 1;
+
+       /* Mark that back-ldif type is in use */
+       cfb->cb_db.bd_info->bi_nDB++;
+
+       cfb->cb_db.be_suffix = be->be_suffix;
+       cfb->cb_db.be_nsuffix = be->be_nsuffix;
+       cfb->cb_db.be_rootdn = be->be_rootdn;
+       cfb->cb_db.be_rootndn = be->be_rootndn;
+
+       ber_str2bv( dir, 0, 1, &cfdir );
+
+       c.be = &cfb->cb_db;
+       c.fname = "slapd";
+       c.argc = 2;
+       argv[0] = "directory";
+       argv[1] = (char *)dir;
+       argv[2] = NULL;
+       c.argv = argv;
+
+       ct = config_find_keyword( c.be->be_cf_table, &c );
+       if ( !ct )
+               return 1;
+
+       if ( config_add_vals( ct, &c ))
+               return 1;
+
+       if ( backend_startup_one( &cfb->cb_db ))
+               return 1;
+
+#if 0  /* not yet */
+       op = (Operation *)opbuf;
+       connection_fake_init( &conn, op, cfb );
+
+       filter.f_desc = slap_schema.si_ad_objectClass;
+       
+       op->o_tag = LDAP_REQ_SEARCH;
+
+       op->ors_filter = &filter;
+       op->ors_filterstr = filterstr;
+       op->ors_scope = LDAP_SCOPE_SUBTREE;
+
+       op->o_dn = be->be_rootdn;
+       op->o_ndn = be->be_rootndn;
+
+       op->o_req_dn = be->be_suffix[0];
+       op->o_req_ndn = be->be_nsuffix[0];
+
+       op->ors_tlimit = SLAP_NO_LIMIT;
+       op->ors_slimit = SLAP_NO_LIMIT;
+
+       op->ors_attrs = slap_anlist_all_attributes;
+       op->ors_attrsonly = 0;
+
+       op->o_callback = &cb;
+       cb.sc_private = cfb;
+
+       op->o_bd = &cfb->cb_db;
+       op->o_bd->be_search( op, &rs );
+#endif
+       
+       return 0;
+}
+
+int
+read_config(const char *fname, const char *dir) {
+       BackendDB *be;
+
+       /* Setup the config backend */
+       be = backend_db_init( "config" );
+       if ( !be )
+               return 1;
+
+       /* Setup the underlying back-ldif backend */
+       if ( config_setup_ldif( be, dir ))
+               return 1;
+
+       ber_str2bv( fname, 0, 1, &cf_prv.c_file );
+
+       return read_config_file(fname, 0, NULL);
+}
+
+static int
+config_back_bind( Operation *op, SlapReply *rs )
+{
+       if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
+               ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
+               /* frontend sends result */
+               return LDAP_SUCCESS;
+       }
+
+       rs->sr_err = LDAP_INVALID_CREDENTIALS;
+       send_ldap_result( op, rs );
+
+       return rs->sr_err;
+}
+
 static int
 config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
 {
@@ -2578,6 +2716,13 @@ config_back_modify( Operation *op, SlapReply *rs )
                goto out;
        }
        ldap_pvt_thread_pool_pause( &connection_pool );
+
+       /* Strategy:
+        * 1) perform the Modify on the cached Entry.
+        * 2) verify that the Entry still satisfies the schema.
+        * 3) perform the individual config operations.
+        * 4) store Modified entry in underlying LDIF backend.
+        */
        ldap_pvt_thread_pool_resume( &connection_pool );
 out:
        send_ldap_result( op, rs );
@@ -2656,6 +2801,7 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc,
 
        vals[0] = oc->soc_cname;
        attr_merge(e, slap_schema.si_ad_objectClass, vals, NULL );
+       attr_merge(e, slap_schema.si_ad_structuralObjectClass, vals, NULL );
        ptr = strchr(rdn->bv_val, '=');
        ad_name.bv_val = rdn->bv_val;
        ad_name.bv_len = ptr - rdn->bv_val;
@@ -2672,14 +2818,15 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc,
                if ((*at)->sat_ad == ad || (*at)->sat_ad == slap_schema.si_ad_cn )
                        continue;
                for (i=0;ct[i].name;i++) {
-                       if (ct[i].ad == (*at)->sat_ad)
+                       if (ct[i].ad == (*at)->sat_ad) {
+                               rc = config_get_vals(&ct[i], c);
+                               if (rc == LDAP_SUCCESS) {
+                                       attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
+                                       ber_bvarray_free( c->rvalue_nvals );
+                                       ber_bvarray_free( c->rvalue_vals );
+                               }
                                break;
-               }
-               rc = config_get_vals(&ct[i], c);
-               if (rc == LDAP_SUCCESS) {
-                       attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
-                       ber_bvarray_free( c->rvalue_nvals );
-                       ber_bvarray_free( c->rvalue_vals );
+                       }
                }
        }
 
@@ -2688,14 +2835,15 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc,
                if ((*at)->sat_ad == ad || (*at)->sat_ad == slap_schema.si_ad_cn )
                        continue;
                for (i=0;ct[i].name;i++) {
-                       if (ct[i].ad == (*at)->sat_ad)
+                       if (ct[i].ad == (*at)->sat_ad) {
+                               rc = config_get_vals(&ct[i], c);
+                               if (rc == LDAP_SUCCESS) {
+                                       attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
+                                       ber_bvarray_free( c->rvalue_nvals );
+                                       ber_bvarray_free( c->rvalue_vals );
+                               }
                                break;
-               }
-               rc = config_get_vals(&ct[i], c);
-               if (rc == LDAP_SUCCESS) {
-                       attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
-                       ber_bvarray_free( c->rvalue_nvals );
-                       ber_bvarray_free( c->rvalue_vals );
+                       }
                }
        }
 
@@ -2717,7 +2865,8 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc,
 }
 
 static CfEntryInfo *
-config_build_includes( ConfigArgs *c, Entry *parent )
+config_build_includes( ConfigArgs *c, Entry *parent,
+       Operation *op, SlapReply *rs )
 {
        Entry *e;
        int i;
@@ -2733,6 +2882,8 @@ config_build_includes( ConfigArgs *c, Entry *parent )
                c->line = (char *)cf;
                config_build_entry( c, e, cfOc_include, &c->value_dn,
                        c->bi->bi_cf_table, NO_TABLE );
+               op->ora_e = e;
+               op->o_bd->be_add( op, rs );
                ce = e->e_private;
                if ( !ceparent->ce_kids ) {
                        ceparent->ce_kids = ce;
@@ -2742,7 +2893,7 @@ config_build_includes( ConfigArgs *c, Entry *parent )
                ceprev = ce;
                if ( cf->c_kids ) {
                        c->line = (char *)cf->c_kids;
-                       config_build_includes( c, e );
+                       config_build_includes( c, e, op, rs );
                }
        }
        return ce;
@@ -2760,6 +2911,25 @@ config_back_db_open( BackendDB *be )
        BackendDB *bptr;
        ConfigArgs c;
        ConfigTable *ct;
+       Connection conn = {0};
+       char opbuf[OPERATION_BUFFER_SIZE];
+       Operation *op;
+       slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
+       SlapReply rs = {REP_RESULT};
+
+       /* If we read the config from back-ldif, nothing to do here */
+       if ( cfb->cb_got_ldif )
+               return 0;
+
+       op = (Operation *)opbuf;
+       connection_fake_init( &conn, op, cfb );
+
+       op->o_dn = be->be_rootdn;
+       op->o_ndn = be->be_rootndn;
+
+       op->o_tag = LDAP_REQ_ADD;
+       op->o_callback = &cb;
+       op->o_bd = &cfb->cb_db;
 
        /* create root of tree */
        rdn = config_rdn;
@@ -2771,6 +2941,8 @@ config_back_db_open( BackendDB *be )
        c.line = (char *)cfb->cb_config;
        ct = c.bi->bi_cf_table;
        config_build_entry( &c, e, cfOc_global, &rdn, ct, NO_TABLE );
+       op->ora_e = e;
+       op->o_bd->be_add( op, &rs );
 
        parent = e;
        ceparent = ce;
@@ -2778,7 +2950,7 @@ config_back_db_open( BackendDB *be )
        /* Create includeFile nodes... */
        if ( cfb->cb_config->c_kids ) {
                c.line = (char *)cfb->cb_config->c_kids;
-               ceprev = config_build_includes( &c, parent );
+               ceprev = config_build_includes( &c, parent, op, &rs );
        }
 
        /* Create backend nodes. Skip if they don't provide a cf_table.
@@ -2798,6 +2970,8 @@ config_back_db_open( BackendDB *be )
                ce->ce_bi = bi;
                c.bi = bi;
                config_build_entry( &c, e, cfOc_backend, &rdn, ct, BI_TABLE );
+               op->ora_e = e;
+               op->o_bd->be_add( op, &rs );
                if ( !ceparent->ce_kids ) {
                        ceparent->ce_kids = ce;
                } else {
@@ -2830,6 +3004,8 @@ config_back_db_open( BackendDB *be )
                ce->ce_be = c.be;
                ce->ce_bi = c.bi;
                config_build_entry( &c, e, cfOc_database, &rdn, ct, BE_TABLE );
+               op->ora_e = e;
+               op->o_bd->be_add( op, &rs );
                if ( !ceparent->ce_kids ) {
                        ceparent->ce_kids = ce;
                } else {
@@ -2854,6 +3030,8 @@ config_back_db_open( BackendDB *be )
                                ce->ce_be = c.be;
                                ce->ce_bi = c.bi;
                                config_build_entry( &c, oe, cfOc_overlay, &rdn, ct, BI_TABLE );
+                               op->ora_e = oe;
+                               op->o_bd->be_add( op, &rs );
                                if ( !opar->ce_kids ) {
                                        opar->ce_kids = ce;
                                } else {
@@ -2862,26 +3040,6 @@ config_back_db_open( BackendDB *be )
                                oprev = ce;
                        }
                }
-#if 0
-               /* Set up ACLs */
-               if ( bptr->be_acl ) {
-                       Entry *ae;
-                       CfEntryInfo *opar = ce;
-
-                       ae = config_alloc_entry( &e->e_nname, &access_rdn );
-                       ce = ae->e_private;
-                       c.be = bptr;
-                       c.bi = bi;
-                       ce->ce_be = c.be;
-                       ce->ce_bi = c.bi;
-                       config_build_entry( &c, ae, cfOc_access, &access_rdn, ct,
-                               NO_TABLE );
-                       if ( opar->ce_kids ) {
-                               ce->ce_sibs = opar->ce_kids;
-                       }
-                       opar->ce_kids = ce;
-               }
-#endif
        }
 
        return 0;
index 48cba471a426626efe619d790d40089645d2b29f..2d5a0f9f90048ff2869d13ad0fc54b480aa82c0d 100644 (file)
@@ -103,55 +103,61 @@ new_config_args( BackendDB *be, const char *fname, int lineno, int argc, char **
        return(c);
 }
 
-int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
+ConfigTable *config_find_keyword(ConfigTable *Conf, ConfigArgs *c) {
+       int i;
+
+       for(i = 0; Conf[i].name; i++)
+               if( (Conf[i].length && (!strncasecmp(c->argv[0], Conf[i].name, Conf[i].length))) ||
+                       (!strcasecmp(c->argv[0], Conf[i].name)) ) break;
+       if ( !Conf[i].name ) return NULL;
+       return Conf+i;
+}
+
+int config_add_vals(ConfigTable *Conf, ConfigArgs *c) {
        int i, rc, arg_user, arg_type, iarg;
        long larg;
        ber_len_t barg;
        void *ptr;
 
-       for(i = 0; Conf[i].name; i++)
-               if( (Conf[i].length && (!strncasecmp(c->argv[0], Conf[i].name, Conf[i].length))) ||
-                       (!strcasecmp(c->argv[0], Conf[i].name)) ) break;
-       if(!Conf[i].name) return(ARG_UNKNOWN);
-       arg_type = Conf[i].arg_type;
+       arg_type = Conf->arg_type;
        if(arg_type == ARG_IGNORED) {
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> ignored\n",
-                       c->log, Conf[i].name, 0);
+                       c->log, Conf->name, 0);
                return(0);
        }
-       if(Conf[i].min_args && (c->argc < Conf[i].min_args)) {
+       if(Conf->min_args && (c->argc < Conf->min_args)) {
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> missing <%s> argument\n",
-                       c->log, Conf[i].name, Conf[i].what);
+                       c->log, Conf->name, Conf->what);
                return(ARG_BAD_CONF);
        }
-       if(Conf[i].max_args && (c->argc > Conf[i].max_args)) {
+       if(Conf->max_args && (c->argc > Conf->max_args)) {
                Debug(LDAP_DEBUG_CONFIG, "%s: extra cruft after <%s> in <%s> line (ignored)\n",
-                       c->log, Conf[i].what, Conf[i].name);
+                       c->log, Conf->what, Conf->name);
        }
        if((arg_type & ARG_DB) && !c->be) {
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> allowed only within database declaration\n",
-                       c->log, Conf[i].name, 0);
+                       c->log, Conf->name, 0);
                return(ARG_BAD_CONF);
        }
        if((arg_type & ARG_PRE_BI) && c->bi) {
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> must appear before any backend %sdeclaration\n",
-                       c->log, Conf[i].name, ((arg_type & ARG_PRE_DB)
+                       c->log, Conf->name, ((arg_type & ARG_PRE_DB)
                        ? "or database " : "") );
                return(ARG_BAD_CONF);
        }
        if((arg_type & ARG_PRE_DB) && c->be && c->be != frontendDB) {
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> must appear before any database declaration\n",
-                       c->log, Conf[i].name, 0);
+                       c->log, Conf->name, 0);
                return(ARG_BAD_CONF);
        }
        if((arg_type & ARG_PAREN) && *c->argv[1] != '(' /*')'*/) {
                Debug(LDAP_DEBUG_CONFIG, "%s: old <%s> format not supported\n",
-                       c->log, Conf[i].name, 0);
+                       c->log, Conf->name, 0);
                return(ARG_BAD_CONF);
        }
-       if((arg_type & ARGS_POINTER) && !Conf[i].arg_item) {
+       if((arg_type & ARGS_POINTER) && !Conf->arg_item && !(arg_type & ARG_OFFSET)) {
                Debug(LDAP_DEBUG_CONFIG, "%s: null arg_item for <%s>\n",
-                       c->log, Conf[i].name, 0);
+                       c->log, Conf->name, 0);
                return(ARG_BAD_CONF);
        }
        c->type = arg_user = (arg_type & ARGS_USERLAND);
@@ -175,7 +181,7 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
                                } else {
                                        Debug(LDAP_DEBUG_CONFIG, "%s: ignoring ", c->log, 0, 0);
                                        Debug(LDAP_DEBUG_CONFIG, "invalid %s value (%s) in <%s> line\n",
-                                               Conf[i].what, c->argv[1], Conf[i].name);
+                                               Conf->what, c->argv[1], Conf->name);
                                        return(0);
                                }
                                break;
@@ -184,7 +190,7 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
                if(iarg < j || larg < j || barg < j ) {
                        larg = larg ? larg : (barg ? barg : iarg);
                        Debug(LDAP_DEBUG_CONFIG, "%s: " , c->log, 0, 0);
-                       Debug(LDAP_DEBUG_CONFIG, "invalid %s value (%ld) in <%s> line\n", Conf[i].what, larg, Conf[i].name);
+                       Debug(LDAP_DEBUG_CONFIG, "invalid %s value (%ld) in <%s> line\n", Conf->what, larg, Conf->name);
                        return(ARG_BAD_CONF);
                }
                switch(arg_type & ARGS_NUMERIC) {
@@ -194,7 +200,9 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
                        case ARG_BER_LEN_T:     c->value_ber_t = barg;          break;
                }
        } else if(arg_type & ARG_STRING) {
-                c->value_string = ch_strdup(c->argv[1]);
+               c->value_string = ch_strdup(c->argv[1]);
+       } else if(arg_type & ARG_BERVAL) {
+               ber_str2bv( c->argv[1], 0, 1, &c->value_bv );
        } else if(arg_type & ARG_DN) {
                struct berval bv;
                ber_str2bv( c->argv[1], 0, 0, &bv );
@@ -202,17 +210,17 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
                if ( rc != LDAP_SUCCESS ) {
                        Debug(LDAP_DEBUG_CONFIG, "%s: " , c->log, 0, 0);
                        Debug(LDAP_DEBUG_CONFIG, "%s DN is invalid %d (%s)\n",
-                               Conf[i].name, rc, ldap_err2string( rc ));
+                               Conf->name, rc, ldap_err2string( rc ));
                        return(ARG_BAD_CONF);
                }
        }
        if(arg_type & ARG_MAGIC) {
                if(!c->be) c->be = frontendDB;
-               rc = (*((ConfigDriver*)Conf[i].arg_item))(c);
+               rc = (*((ConfigDriver*)Conf->arg_item))(c);
                if(c->be == frontendDB) c->be = NULL;
                if(rc) {
                        Debug(LDAP_DEBUG_CONFIG, "%s: handler for <%s> exited with %d!",
-                               c->log, Conf[i].name, rc);
+                               c->log, Conf->name, rc);
                        return(ARG_BAD_CONF);
                }
                return(0);
@@ -224,14 +232,15 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
                        ptr = c->bi->bi_private;
                else {
                        Debug(LDAP_DEBUG_CONFIG, "%s: offset for <%s> missing base pointer!",
-                               c->log, Conf[i].name, 0);
+                               c->log, Conf->name, 0);
                        return(ARG_BAD_CONF);
                }
-               ptr = (void *)((char *)ptr + (int)Conf[i].arg_item);
+               ptr = (void *)((char *)ptr + (int)Conf->arg_item);
        } else if (arg_type & ARGS_POINTER) {
-               ptr = Conf[i].arg_item;
+               ptr = Conf->arg_item;
        }
-       if(arg_type & ARGS_POINTER) switch(arg_type & ARGS_POINTER) {
+       if(arg_type & ARGS_POINTER)
+               switch(arg_type & ARGS_POINTER) {
                        case ARG_ON_OFF:
                        case ARG_INT:           *(int*)ptr = iarg;                      break;
                        case ARG_LONG:          *(long*)ptr = larg;                     break;
@@ -241,7 +250,7 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
                                if(cc) {
                                        if (arg_type & ARG_UNIQUE) {
                                                Debug(LDAP_DEBUG_CONFIG, "%s: already set %s!\n",
-                                                       c->log, Conf[i].name, 0 );
+                                                       c->log, Conf->name, 0 );
                                                return(ARG_BAD_CONF);
                                        }
                                        ch_free(cc);    /* potential memory leak */
@@ -249,10 +258,19 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
                                *(char **)ptr = c->value_string;
                                break;
                                }
-       }
+                       case ARG_BERVAL:
+                               *(struct berval *)ptr = c->value_bv;
+                               break;
+               }
        return(arg_user);
 }
 
+int
+config_del_vals(ConfigTable *cf, ConfigArgs *c)
+{
+       int rc = 0;
+}
+
 int
 config_get_vals(ConfigTable *cf, ConfigArgs *c)
 {
@@ -267,7 +285,7 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c)
        memset(&c->values, 0, sizeof(c->values));
        c->rvalue_vals = NULL;
        c->rvalue_nvals = NULL;
-       c->emit = 1;
+       c->op = SLAP_CONFIG_EMIT;
        c->type = cf->arg_type & ARGS_USERLAND;
 
        if ( cf->arg_type & ARG_MAGIC ) {
@@ -295,14 +313,16 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c)
                        if ( *(char **)ptr )
                                c->value_string = ch_strdup(*(char **)ptr);
                        break;
+               case ARG_BERVAL:
+                       ber_dupbv( &c->value_bv, (struct berval *)ptr ); break;
                }
        }
        if ( cf->arg_type & ARGS_POINTER) {
                bv.bv_val = c->log;
                switch(cf->arg_type & ARGS_POINTER) {
                case ARG_INT: bv.bv_len = sprintf(bv.bv_val, "%d", c->value_int); break;
-               case ARG_LONG: bv.bv_len = sprintf(bv.bv_val, "%l", c->value_long); break;
-               case ARG_BER_LEN_T: bv.bv_len =sprintf(bv.bv_val, "%l",c->value_ber_t); break;
+               case ARG_LONG: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_long); break;
+               case ARG_BER_LEN_T: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_ber_t); break;
                case ARG_ON_OFF: bv.bv_len = sprintf(bv.bv_val, "%s",
                        c->value_int ? "TRUE" : "FALSE"); break;
                case ARG_STRING:
@@ -312,6 +332,13 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c)
                                return 1;
                        }
                        break;
+               case ARG_BERVAL:
+                       if ( !BER_BVISEMPTY( &c->value_bv )) {
+                               bv = c->value_bv;
+                       } else {
+                               return 1;
+                       }
+                       break;
                }
                if (( cf->arg_type & ARGS_POINTER ) == ARG_STRING )
                        ber_bvarray_add(&c->rvalue_vals, &bv);
@@ -388,6 +415,7 @@ int
 read_config_file(const char *fname, int depth, ConfigArgs *cf)
 {
        FILE *fp;
+       ConfigTable *ct;
        ConfigArgs *c;
        int rc;
 
@@ -439,58 +467,67 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf)
                        continue;
                }
 
-               rc = parse_config_table( config_back_cf_table, c );
-               if ( !rc ) {
-                       continue;
-               }
-               if ( rc & ARGS_USERLAND ) {
-                       switch(rc) {    /* XXX a usertype would be opaque here */
-                       default:
-                               Debug(LDAP_DEBUG_CONFIG, "%s: unknown user type <%d>\n",
-                                       c->log, *c->argv, 0);
+               c->op = LDAP_MOD_ADD;
+
+               ct = config_find_keyword( config_back_cf_table, c );
+               if ( ct ) {
+                       rc = config_add_vals( ct, c );
+                       if ( !rc ) continue;
+
+                       if ( rc & ARGS_USERLAND ) {
+                               /* XXX a usertype would be opaque here */
+                               Debug(LDAP_DEBUG_CONFIG, "%s: unknown user type <%s>\n",
+                                       c->log, c->argv[0], 0);
                                goto badline;
-                       }
 
-               } else if ( rc == ARG_BAD_CONF || rc != ARG_UNKNOWN ) {
-                       goto badline;
+                       } else if ( rc == ARG_BAD_CONF ) {
+                               goto badline;
+                       }
                        
-               } else if ( c->bi && c->bi->bi_config ) {               /* XXX to check: could both be/bi_config? oops */
-                       rc = (*c->bi->bi_config)(c->bi, c->fname, c->lineno, c->argc, c->argv);
+               } else if ( c->bi ) {
+                       rc = SLAP_CONF_UNKNOWN;
+                       if ( c->bi->bi_cf_table ) {
+                               ct = config_find_keyword( c->bi->bi_cf_table, c );
+                               if ( ct ) {
+                                       rc = config_add_vals( ct, c );
+                               }
+                       } else if ( c->bi->bi_config ) {
+                               rc = (*c->bi->bi_config)(c->bi, c->fname, c->lineno,
+                                       c->argc, c->argv);
+                       }
                        if ( rc ) {
                                switch(rc) {
                                case SLAP_CONF_UNKNOWN:
                                        Debug(LDAP_DEBUG_CONFIG, "%s: "
                                                "unknown directive <%s> inside backend info definition (ignored)\n",
-                                               c->log, *c->argv, 0);
+                                               c->log, *c->argv, 0);
                                        continue;
                                default:
                                        goto badline;
                                }
                        }
-                       
+
                } else if ( c->be ) {
+                       rc = SLAP_CONF_UNKNOWN;
                        if ( c->be->be_cf_table ) {
-                               rc = parse_config_table( c->be->be_cf_table, c );
-
-                               if ( !rc ) continue;
-
-                               if ( rc != ARG_UNKNOWN ) goto badline;
-                       }
-
-                       if ( c->be->be_config ) {
+                               ct = config_find_keyword( c->be->be_cf_table, c );
+                               if ( ct ) {
+                                       rc = config_add_vals( ct, c );
+                               }
+                       } else if ( c->be->be_config ) {
                                rc = (*c->be->be_config)(c->be, c->fname, c->lineno,
                                        c->argc, c->argv);
-                               if ( rc ) {
-                                       switch(rc) {
-                                       case SLAP_CONF_UNKNOWN:
-                                               Debug( LDAP_DEBUG_CONFIG, "%s: "
-                                                       "unknown directive <%s> inside backend database "
-                                                       "definition (ignored)\n",
-                                                       c->log, *c->argv, 0);
-                                               continue;
-                                       default:
-                                               goto badline;
-                                       }
+                       }
+                       if ( rc ) {
+                               switch(rc) {
+                               case SLAP_CONF_UNKNOWN:
+                                       Debug( LDAP_DEBUG_CONFIG, "%s: "
+                                               "unknown directive <%s> inside backend database "
+                                               "definition (ignored)\n",
+                                               c->log, *c->argv, 0);
+                                       continue;
+                               default:
+                                       goto badline;
                                }
                        }
 
@@ -929,3 +966,24 @@ slap_str2clist( char ***out, char *in, const char *brkstr )
        free( str );
        return( *out );
 }
+
+int config_generic_wrapper( Backend *be, const char *fname, int lineno,
+       int argc, char **argv )
+{
+       ConfigArgs c = { 0 };
+       ConfigTable *ct;
+       int rc;
+
+       c.be = be;
+       c.fname = fname;
+       c.lineno = lineno;
+       c.argc = argc;
+       c.argv = argv;
+       sprintf( c.log, "%s: line %lu", fname, lineno );
+
+       rc = SLAP_CONF_UNKNOWN;
+       ct = config_find_keyword( be->be_cf_table, &c );
+       if ( ct )
+               rc = config_add_vals( ct, &c );
+       return rc;
+}
index d43c442977786dc20e4bef82797de18dbe987a5f..b9b9466f1b594b8fdc2bf8704fc5f64a1bebd67f 100644 (file)
@@ -29,15 +29,15 @@ typedef struct ConfigTable {
 
 #define ARGS_USERLAND  0x00000fff
 #define ARGS_TYPES     0x000ff000
-#define ARGS_POINTER   0x0001f000
+#define ARGS_POINTER   0x0003f000
 #define ARGS_NUMERIC   0x0000f000
 #define ARG_INT                0x00001000
 #define ARG_LONG       0x00002000
 #define ARG_BER_LEN_T  0x00004000
 #define ARG_ON_OFF     0x00008000
 #define ARG_STRING     0x00010000
-#define ARG_DN         0x00020000
-#define ARG_EXISTS     0x00040000      /* XXX not yet */
+#define ARG_BERVAL     0x00020000
+#define ARG_DN         0x00040000
 #define ARG_IGNORED    0x00080000
 
 #define ARGS_SYNTAX    0xfff00000
@@ -77,6 +77,7 @@ typedef struct config_args_s {
                long v_long;
                ber_len_t v_ber_t;
                char *v_string;
+               struct berval v_bv;
                struct {
                        struct berval vdn_dn;
                        struct berval vdn_ndn;
@@ -85,7 +86,8 @@ typedef struct config_args_s {
        /* return values for emit mode */
        BerVarray rvalue_vals;
        BerVarray rvalue_nvals;
-       int emit;       /* emit instead of setting */
+#define        SLAP_CONFIG_EMIT        0x2000  /* emit instead of set */
+       int op;
        int type;       /* ConfigTable.arg_type & ARGS_USERLAND */
        BackendDB *be;
        BackendInfo *bi;
@@ -95,9 +97,12 @@ typedef struct config_args_s {
 #define value_long values.v_long
 #define value_ber_t values.v_ber_t
 #define value_string values.v_string
+#define value_bv values.v_bv
 #define value_dn values.v_dn.vdn_dn
 #define value_ndn values.v_dn.vdn_ndn
 
 typedef int (ConfigDriver)(ConfigArgs *c);
 
 int config_get_vals(ConfigTable *ct, ConfigArgs *c);
+int config_add_vals(ConfigTable *ct, ConfigArgs *c);
+ConfigTable * config_find_keyword(ConfigTable *ct, ConfigArgs *c);
index c88876e046dcfbc2c281e7f92d2ed4144a9ffab9..944faff679c8cefdb3285fe57b004a65dbf3035b 100644 (file)
@@ -253,8 +253,10 @@ int main( int argc, char **argv )
 
 #ifdef HAVE_NT_SERVICE_MANAGER
        char            *configfile = ".\\slapd.conf";
+       char            *configdir = ".\\slapd.d";
 #else
        char            *configfile = SLAPD_DEFAULT_CONFIGFILE;
+       char            *configdir = SLAPD_DEFAULT_CONFIGDIR;
 #endif
        char        *serverName;
        int         serverMode = SLAP_SERVER_MODE;
@@ -288,6 +290,7 @@ int main( int argc, char **argv )
        {
                int *i;
                char *newConfigFile;
+               char *newConfigDir;
                char *newUrls;
                char *regService = NULL;
 
@@ -319,11 +322,17 @@ int main( int argc, char **argv )
                        configfile = newConfigFile;
                        Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", configfile, 0, 0 );
                }
+
+               newConfigDir = (char*)lutil_getRegParam( regService, "ConfigDir" );
+               if ( newConfigDir != NULL ) {
+                       configdir = newConfigDir;
+                       Debug ( LDAP_DEBUG_ANY, "new config dir from registry is: %s\n", configdir, 0, 0 );
+               }
        }
 #endif
 
        while ( (i = getopt( argc, argv,
-                            "c:d:f:h:n:o:s:StT:V"
+                            "c:d:f:F:h:n:o:s:StT:V"
 #if LDAP_PF_INET6
                                "46"
 #endif
@@ -385,6 +394,10 @@ int main( int argc, char **argv )
                        configfile = ch_strdup( optarg );
                        break;
 
+               case 'F':       /* use config dir */
+                       configdir = ch_strdup( optarg );
+                       break;
+
                case 'o': {
                        char            *val = strchr( optarg, '=' );
                        struct berval   opt;
@@ -624,7 +637,7 @@ unhandled_option:;
        }
 #endif /* SLAP_DYNACL */
 
-       if ( read_config( configfile, 0 ) != 0 ) {
+       if ( read_config( configfile, configdir ) != 0 ) {
                rc = 1;
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
 
index be1ce92e6052daeb9d228c83dee12d018c8d4a6f..f91874a5aee67b688fe253a9af297f043ae6c603 100644 (file)
@@ -439,7 +439,7 @@ LDAP_SLAPD_F (int) slap_global_control LDAP_P ((
 /*
  * config.c
  */
-LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname, int depth ));
+LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname, const char *dir ));
 LDAP_SLAPD_F (void) config_destroy LDAP_P ((void));
 LDAP_SLAPD_F (char **) slap_str2clist LDAP_P((
        char ***, char *, const char * ));
@@ -454,6 +454,8 @@ LDAP_SLAPD_F (int) bindconf_parse LDAP_P((
 LDAP_SLAPD_F (int) bindconf_unparse LDAP_P((
        slap_bindconf *bc, struct berval *bv ));
 LDAP_SLAPD_F (void) bindconf_free LDAP_P(( slap_bindconf *bc ));
+LDAP_SLAPD_F (int) config_generic_wrapper LDAP_P(( Backend *be,
+       const char *fname, int lineno, int argc, char **argv ));
 
 #ifdef LDAP_SLAPI
 LDAP_SLAPD_V (int) slapi_plugins_used;
index b49c6c53256639cf16ef42bb5d389cf5e0579806..4a0c55a600dd3c9527f81981c0179877251ea9c1 100644 (file)
@@ -108,6 +108,7 @@ slap_tool_init(
 {
        char *options;
        char *conffile = SLAPD_DEFAULT_CONFIGFILE;
+       char *confdir = SLAPD_DEFAULT_CONFIGDIR;
        struct berval base = BER_BVNULL;
        char *filterstr = NULL;
        char *subtree = NULL;
@@ -127,36 +128,36 @@ slap_tool_init(
 
        switch( tool ) {
        case SLAPADD:
-               options = "b:cd:f:l:n:qtuvw";
+               options = "b:cd:f:F:l:n:qtuvw";
                break;
 
        case SLAPCAT:
-               options = "a:b:cd:f:l:n:s:v";
+               options = "a:b:cd:f:F:l:n:s:v";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
        case SLAPDN:
-               options = "d:f:v";
+               options = "d:f:F:v";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
        case SLAPTEST:
-               options = "d:f:uv";
+               options = "d:f:F:uv";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
        case SLAPAUTH:
-               options = "d:f:M:R:U:vX:";
+               options = "d:f:F:M:R:U:vX:";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
        case SLAPINDEX:
-               options = "b:cd:f:n:qv";
+               options = "b:cd:f:F:n:qv";
                mode |= SLAP_TOOL_READMAIN;
                break;
 
        case SLAPACL:
-               options = "b:D:d:f:U:v";
+               options = "b:D:d:f:F:U:v";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
@@ -192,6 +193,10 @@ slap_tool_init(
                        conffile = strdup( optarg );
                        break;
 
+               case 'F':       /* specify a conf dir */
+                       confdir = strdup( optarg );
+                       break;
+
                case 'l':       /* LDIF file */
                        ldiffile = strdup( optarg );
                        break;
@@ -336,7 +341,7 @@ slap_tool_init(
                exit( EXIT_FAILURE );
        }
 
-       rc = read_config( conffile, 0 );
+       rc = read_config( conffile, confdir );
 
        if ( rc != 0 ) {
                fprintf( stderr, "%s: bad configuration file!\n", progname );