From bc4564cac44a5a4bd0480fdaddadbb1db2a18d9c Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 15 Mar 2005 08:57:34 +0000 Subject: [PATCH] More back-config / back-ldif integration, added config_generic_wrapper, added -F option to specify config directory --- servers/slapd/back-bdb/config.c | 23 +-- servers/slapd/back-bdb/init.c | 2 +- servers/slapd/back-ldif/ldif.c | 78 ++++--- servers/slapd/bconfig.c | 356 +++++++++++++++++++++++--------- servers/slapd/config.c | 192 +++++++++++------ servers/slapd/config.h | 13 +- servers/slapd/main.c | 17 +- servers/slapd/proto-slap.h | 4 +- servers/slapd/slapcommon.c | 21 +- 9 files changed, 475 insertions(+), 231 deletions(-) diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c index a6d4d28e68..84bfb5e724 100644 --- a/servers/slapd/back-bdb/config.c +++ b/servers/slapd/back-bdb/config.c @@ -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; -} diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 8893333fc3..e202de4cfc 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -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; diff --git a/servers/slapd/back-ldif/ldif.c b/servers/slapd/back-ldif/ldif.c index 56f147489d..4756b4a9d2 100644 --- a/servers/slapd/back-ldif/ldif.c +++ b/servers/slapd/back-ldif/ldif.c @@ -29,6 +29,7 @@ #include #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 in \"directory \" 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; } diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 577b330953..ae499a5ec5 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -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; diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 48cba471a4..2d5a0f9f90 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -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; +} diff --git a/servers/slapd/config.h b/servers/slapd/config.h index d43c442977..b9b9466f1b 100644 --- a/servers/slapd/config.h +++ b/servers/slapd/config.h @@ -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); diff --git a/servers/slapd/main.c b/servers/slapd/main.c index c88876e046..944faff679 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -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 ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index be1ce92e60..f91874a5ae 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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; diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index b49c6c5325..4a0c55a600 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -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 ); -- 2.39.5