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
static char *logfileName;
static BerVarray authz_rewrites;
+static struct berval cfdir;
+
static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
*cfAd_include;
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;
"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' "
{ "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,
{ "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,
{ "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,
"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 $ "
char *p;
int i;
- if ( c->emit ) {
+ if ( c->op == SLAP_CONFIG_EMIT ) {
int rc = 0;
switch(c->type) {
case CFG_CONCUR:
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;
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);
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);
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;
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;
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;
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])) {
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 );
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);
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;
{ 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 );
}
{ 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);
{ 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);
{ 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);
{ BER_BVNULL, 0 }
};
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return mask_to_verbs( loglevel_ops, ldap_syslog, &c->rvalue_vals );
}
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 );
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;
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;
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++) {
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);
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;
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));
"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);
"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) {
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 )
{
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 )
{
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 );
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;
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 );
+ }
}
}
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 );
+ }
}
}
}
static CfEntryInfo *
-config_build_includes( ConfigArgs *c, Entry *parent )
+config_build_includes( ConfigArgs *c, Entry *parent,
+ Operation *op, SlapReply *rs )
{
Entry *e;
int i;
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;
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;
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;
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;
/* 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.
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 {
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 {
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 {
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;
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);
} 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;
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) {
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 );
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);
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;
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 */
*(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)
{
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 ) {
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:
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);
read_config_file(const char *fname, int depth, ConfigArgs *cf)
{
FILE *fp;
+ ConfigTable *ct;
ConfigArgs *c;
int rc;
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;
}
}
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;
+}