CFG_SSTR_IF_MAX,
CFG_SSTR_IF_MIN,
CFG_TTHREADS,
+ CFG_MIRRORMODE,
CFG_LAST
};
* OLcfgOv{Oc|At}:7 -> distproc
* OLcfgOv{Oc|At}:8 -> dynlist
* OLcfgOv{Oc|At}:9 -> dds
+ * OLcfgOv{Oc|At}:10 -> unique
+ * OLcfgOv{Oc|At}:11 -> refint
+ * OLcfgOv{Oc|At}:12 -> ppolicy
+ * OLcfgOv{Oc|At}:13 -> constraint
+ * OLcfgOv{Oc|At}:14 -> translucent
*/
/* alphabetical ordering */
&config_generic, "( OLcfgGlAt:5 NAME 'olcAttributeOptions' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString )", NULL, NULL },
- { "attribute", "attribute", 2, 0, 9,
+ { "attribute", "attribute", 2, 0, STRLENOF( "attribute" ),
ARG_PAREN|ARG_MAGIC|CFG_ATTR|ARG_NO_DELETE|ARG_NO_INSERT,
&config_generic, "( OLcfgGlAt:4 NAME 'olcAttributeTypes' "
"DESC 'OpenLDAP attributeTypes' "
{ "maxDerefDepth", "depth", 2, 2, 0, ARG_DB|ARG_INT|ARG_MAGIC|CFG_DEPTH,
&config_generic, "( OLcfgDbAt:0.6 NAME 'olcMaxDerefDepth' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+ { "mirrormode", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_MIRRORMODE,
+ &config_generic, "( OLcfgDbAt:0.16 NAME 'olcMirrorMode' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "moduleload", "file", 2, 0, 0,
#ifdef SLAPD_MODULES
ARG_MAGIC|CFG_MODLOAD, &config_generic,
{ "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
&syncrepl_config, "( OLcfgDbAt:0.11 NAME 'olcSyncrepl' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
- { "threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_THREADS,
- &config_generic, "( OLcfgGlAt:66 NAME 'olcThreads' "
+ { "threads", "count", 2, 2, 0,
+#ifdef NO_THREADS
+ ARG_IGNORED, NULL,
+#else
+ ARG_INT|ARG_MAGIC|CFG_THREADS, &config_generic,
+#endif
+ "( OLcfgGlAt:66 NAME 'olcThreads' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "timelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
&config_timelimit, "( OLcfgGlAt:67 NAME 'olcTimeLimit' "
"olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ "
"olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
"olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
- "olcTimeLimit $ olcUpdateDN $ olcUpdateRef ) )",
+ "olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode ) )",
Cft_Database, NULL, cfAddDatabase },
{ "( OLcfgGlOc:5 "
"NAME 'olcOverlayConfig' "
AC_MEMCPY( abv.bv_val, ibuf, abv.bv_len );
/* Turn TAB / EOL into plain space */
for (src=bv.bv_val,dst=abv.bv_val+abv.bv_len; *src; src++) {
- if (isspace(*src)) *dst++ = ' ';
+ if (isspace((unsigned char)*src)) *dst++ = ' ';
else *dst++ = *src;
}
*dst = '\0';
case CFG_LASTMOD:
c->value_int = (SLAP_NOLASTMOD(c->be) == 0);
break;
+ case CFG_MIRRORMODE:
+ if ( SLAP_SHADOW(c->be))
+ c->value_int = (SLAP_SINGLE_SHADOW(c->be) == 0);
+ else
+ rc = 1;
+ break;
case CFG_SSTR_IF_MAX:
c->value_int = index_substr_if_maxlen;
break;
case CFG_AZPOLICY:
case CFG_DEPTH:
case CFG_LASTMOD:
+ case CFG_MIRRORMODE:
case CFG_SASLSECP:
case CFG_SSTR_IF_MAX:
case CFG_SSTR_IF_MIN:
break;
case CFG_THREADS:
- if ( c->value_int > 2 * SLAP_MAX_WORKER_THREADS ) {
+ if ( c->value_int < 2 ) {
+ snprintf( c->msg, sizeof( c->msg ),
+ "threads=%d smaller than minimum value 2",
+ c->value_int );
+ Debug(LDAP_DEBUG_ANY, "%s: %s.\n",
+ c->log, c->msg, 0 );
+ return 1;
+
+ } else if ( c->value_int > 2 * SLAP_MAX_WORKER_THREADS ) {
snprintf( c->msg, sizeof( c->msg ),
"warning, threads=%d larger than twice the default (2*%d=%d); YMMV",
c->value_int, SLAP_MAX_WORKER_THREADS, 2 * SLAP_MAX_WORKER_THREADS );
SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NOLASTMOD;
break;
+ case CFG_MIRRORMODE:
+ if(!SLAP_SHADOW(c->be)) {
+ snprintf( c->msg, sizeof( c->msg ), "<%s> database is not a shadow",
+ c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+ c->log, c->msg, 0 );
+ return(1);
+ }
+ if(c->value_int)
+ SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_SINGLE_SHADOW;
+ else
+ SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_SINGLE_SHADOW;
+ break;
+
case CFG_SSTR_IF_MAX:
if (c->value_int < index_substr_if_minlen) {
snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
char *ptr;
if ( c->op == SLAP_CONFIG_ADD ) {
ptr = c->line + STRLENOF("moduleload");
- while (!isspace(*ptr)) ptr++;
- while (isspace(*ptr)) ptr++;
+ while (!isspace((unsigned char) *ptr)) ptr++;
+ while (isspace((unsigned char) *ptr)) ptr++;
} else {
ptr = c->line;
}
default:
- Debug( SLAPD_DEBUG_CONFIG_ERROR,
- "%s: unknown CFG_TYPE %d"
- SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+ Debug( LDAP_DEBUG_ANY,
+ "%s: unknown CFG_TYPE %d.\n",
c->log, c->type, 0 );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
}
return(0);
}
if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1])) {
/* log error */
- Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: (optional) %s overlay \"%s\" configuration failed"
- SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+ Debug( LDAP_DEBUG_ANY,
+ "%s: (optional) %s overlay \"%s\" configuration failed.\n",
c->log, c->be == frontendDB ? "global " : "", &c->argv[1][1]);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
} else if(overlay_config(c->be, c->argv[1])) {
return(1);
}
ndn = c->value_ndn;
tbe = select_backend(&ndn, 0, 0);
if(tbe == c->be) {
- Debug( SLAPD_DEBUG_CONFIG_ERROR,
- "%s: suffix already served by this backend!"
- SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+ Debug( LDAP_DEBUG_ANY, "%s: suffix already served by this backend!.\n",
c->log, 0, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
free(pdn.bv_val);
free(ndn.bv_val);
} else if(tbe) {
rc = slap_verbmasks_append( &loglevel_ops, i, s, loglevel_ignore );
if ( rc != 0 ) {
- Debug( LDAP_DEBUG_ANY, "slap_loglevel_register(%lu, \"%s\") failed\n",
+ Debug( LDAP_DEBUG_ANY, "slap_loglevel_get(%lu, \"%s\") failed\n",
i, s->bv_val, 0 );
} else {
for( i=1; i < c->argc; i++ ) {
int level;
- if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) {
+ if ( isdigit((unsigned char)c->argv[i][0]) || c->argv[i][0] == '-' ) {
if( lutil_atoi( &level, c->argv[i] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
} else if(!strncasecmp(c->argv[i], "suffix=", STRLENOF( "suffix="))) {
switch(add_replica_suffix(c->be, nr, c->argv[i] + STRLENOF("suffix="))) {
case 1:
- Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
- "suffix \"%s\" in \"replica\" line is not valid for backend"
- SLAPD_CONF_UNKNOWN_IGNORED ".\n",
- c->log, c->argv[i] + STRLENOF("suffix="), 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+ Debug( LDAP_DEBUG_ANY, "%s: "
+ "suffix \"%s\" in \"replica\" line is not valid for backend.\n",
+ c->log, c->argv[i] + STRLENOF("suffix="), 0);
return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
break;
case 2:
- Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
- "unable to normalize suffix in \"replica\" line"
- SLAPD_CONF_UNKNOWN_IGNORED ".\n",
- c->log, 0, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+ Debug( LDAP_DEBUG_ANY, "%s: "
+ "unable to normalize suffix in \"replica\" line.\n",
+ c->log, 0, 0);
return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
break;
}
return 1;
}
- SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | flag);
+ SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SINGLE_SHADOW | flag);
return 0;
}
static int
config_tls_option(ConfigArgs *c) {
int flag;
+ LDAP *ld = slap_tls_ld;
switch(c->type) {
- case CFG_TLS_RAND: flag = LDAP_OPT_X_TLS_RANDOM_FILE; break;
+ case CFG_TLS_RAND: flag = LDAP_OPT_X_TLS_RANDOM_FILE; ld = NULL; break;
case CFG_TLS_CIPHER: flag = LDAP_OPT_X_TLS_CIPHER_SUITE; break;
case CFG_TLS_CERT_FILE: flag = LDAP_OPT_X_TLS_CERTFILE; break;
case CFG_TLS_CERT_KEY: flag = LDAP_OPT_X_TLS_KEYFILE; break;
return 1;
}
if (c->op == SLAP_CONFIG_EMIT) {
- return ldap_pvt_tls_get_option( NULL, flag, &c->value_string );
+ return ldap_pvt_tls_get_option( ld, flag, &c->value_string );
} else if ( c->op == LDAP_MOD_DELETE ) {
- return ldap_pvt_tls_set_option( NULL, flag, NULL );
+ return ldap_pvt_tls_set_option( ld, flag, NULL );
}
ch_free(c->value_string);
- return(ldap_pvt_tls_set_option(NULL, flag, c->argv[1]));
+ return(ldap_pvt_tls_set_option(ld, flag, c->argv[1]));
}
/* FIXME: this ought to be provided by libldap */
return 1;
}
if (c->op == SLAP_CONFIG_EMIT) {
- ldap_pvt_tls_get_option( NULL, flag, &c->value_int );
+ ldap_pvt_tls_get_option( slap_tls_ld, flag, &c->value_int );
for (i=0; !BER_BVISNULL(&keys[i].word); i++) {
if (keys[i].mask == c->value_int) {
c->value_string = ch_strdup( keys[i].word.bv_val );
return 1;
} else if ( c->op == LDAP_MOD_DELETE ) {
int i = 0;
- return ldap_pvt_tls_set_option( NULL, flag, &i );
+ return ldap_pvt_tls_set_option( slap_tls_ld, flag, &i );
}
ch_free( c->value_string );
if ( isdigit( (unsigned char)c->argv[1][0] ) ) {
c->log, c->argv[0], c->argv[1] );
return 1;
}
- return(ldap_pvt_tls_set_option(NULL, flag, &i));
+ return(ldap_pvt_tls_set_option(slap_tls_ld, flag, &i));
} else {
- return(ldap_int_tls_config(NULL, flag, c->argv[1]));
+ return(ldap_int_tls_config(slap_tls_ld, flag, c->argv[1]));
}
}
#endif
* These entries can have auto-assigned indexes (appended to the end)
* but only the other types support auto-renumbering of siblings.
*/
- rc = check_name_index( last, colst[0]->co_type, e, rs, renum );
- if ( rc )
- goto done;
+ {
+ int renumber = renum ? *renum : 0;
+ rc = check_name_index( last, colst[0]->co_type, e, rs, renum );
+ if ( rc ) {
+ goto done;
+ }
+ if ( renum && *renum && renumber == -1 ) {
+ snprintf( ca->msg, sizeof( ca->msg ),
+ "operation requires sibling renumbering" );
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ goto done;
+ }
+ }
init_config_argv( ca );
* 4) store entry in underlying database
* 5) perform any necessary renumbering
*/
+ /* NOTE: by now we do not accept adds that require renumbering */
+ renumber = -1;
rs->sr_err = config_add_internal( cfb, op->ora_e, &ca, rs, &renumber );
if ( rs->sr_err != LDAP_SUCCESS ) {
rs->sr_text = ca.msg;
- } else if ( cfb->cb_use_ldif ) {
+ goto out2;
+ }
+
+ if ( cfb->cb_use_ldif ) {
BackendDB *be = op->o_bd;
slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
struct berval dn, ndn;
op->o_dn = dn;
op->o_ndn = ndn;
}
+
if ( renumber ) {
+ /* TODO */
}
+out2:;
ldap_pvt_thread_pool_resume( &connection_pool );
-out:
+out:;
send_ldap_result( op, rs );
return rs->sr_err;
}
}
ch_free( ca->argv );
if ( colst ) ch_free( colst );
+ while( dels ) {
+ deltail = dels->next;
+ ch_free( dels );
+ dels = deltail;
+ }
return rc;
}
}
ldap_pvt_thread_pool_pause( &connection_pool );
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ rs->sr_text = "renaming not implemented yet within naming context";
+
ldap_pvt_thread_pool_resume( &connection_pool );
out:
send_ldap_result( op, rs );
ObjectClass *oc;
CfEntryInfo *ceprev = NULL;
+ Debug( LDAP_DEBUG_TRACE, "config_build_entry: \"%s\"\n", rdn->bv_val, 0, 0);
e->e_private = ce;
ce->ce_entry = e;
ce->ce_parent = parent;
if ( op ) {
op->ora_e = e;
op->o_bd->be_add( op, rs );
+ if ( ( rs->sr_err != LDAP_SUCCESS )
+ && (rs->sr_err != LDAP_ALREADY_EXISTS) ) {
+ return NULL;
+ }
}
if ( ceprev ) {
ceprev->ce_sibs = ce;
return e;
}
-static void
+static int
config_build_schema_inc( ConfigArgs *c, CfEntryInfo *ceparent,
Operation *op, SlapReply *rs )
{
c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=" SLAP_X_ORDERED_FMT, c->depth);
if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
/* FIXME: how can indicate error? */
- return;
+ return -1;
}
strncpy( c->value_dn.bv_val + c->value_dn.bv_len, bv.bv_val,
bv.bv_len );
c->private = cf;
e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
&CFOC_SCHEMA, NULL );
- if ( e && cf->c_kids ) {
+ if ( !e ) {
+ return -1;
+ } else if ( e && cf->c_kids ) {
c->private = cf->c_kids;
config_build_schema_inc( c, e->e_private, op, rs );
}
}
+ return 0;
}
-static void
+static int
config_build_includes( ConfigArgs *c, CfEntryInfo *ceparent,
Operation *op, SlapReply *rs )
{
c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=include" SLAP_X_ORDERED_FMT, i);
if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
/* FIXME: how can indicate error? */
- return;
+ return -1;
}
c->private = cf;
e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
&CFOC_INCLUDE, NULL );
- if ( e && cf->c_kids ) {
+ if ( ! e ) {
+ return -1;
+ } else if ( e && cf->c_kids ) {
c->private = cf->c_kids;
config_build_includes( c, e->e_private, op, rs );
}
}
+ return 0;
}
#ifdef SLAPD_MODULES
-static void
+static int
config_build_modules( ConfigArgs *c, CfEntryInfo *ceparent,
Operation *op, SlapReply *rs )
{
c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=module" SLAP_X_ORDERED_FMT, i);
if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
/* FIXME: how can indicate error? */
- return;
+ return -1;
}
c->private = mp;
- config_build_entry( op, rs, ceparent, c, &c->value_dn,
- &CFOC_MODULE, NULL );
+ if ( ! config_build_entry( op, rs, ceparent, c, &c->value_dn, &CFOC_MODULE, NULL )) {
+ return -1;
+ }
}
+ return 0;
}
#endif
SlapReply rs = {REP_RESULT};
void *thrctx = NULL;
+ Debug( LDAP_DEBUG_TRACE, "config_back_db_open\n", 0, 0, 0);
/* If we read the config from back-ldif, nothing to do here */
if ( cfb->cb_got_ldif )
return 0;
c.private = cfb->cb_config;
c.be = frontendDB;
e = config_build_entry( op, &rs, NULL, &c, &rdn, &CFOC_GLOBAL, NULL );
+ if ( !e ) {
+ return -1;
+ }
ce = e->e_private;
cfb->cb_root = ce;
if ( cfb->cb_config->c_kids ) {
c.depth = 0;
c.private = cfb->cb_config->c_kids;
- config_build_includes( &c, ceparent, op, &rs );
+ if ( config_build_includes( &c, ceparent, op, &rs ) ) {
+ return -1;
+ }
}
#ifdef SLAPD_MODULES
/* Create Module nodes... */
if ( modpaths.mp_loads ) {
- config_build_modules( &c, ceparent, op, &rs );
+ if ( config_build_modules( &c, ceparent, op, &rs ) ){
+ return -1;
+ }
}
#endif
rdn = schema_rdn;
c.private = NULL;
e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_SCHEMA, NULL );
+ if ( !e ) {
+ return -1;
+ }
ce = e->e_private;
/* Create schema nodes for included schema... */
if ( cfb->cb_config->c_kids ) {
c.depth = 0;
c.private = cfb->cb_config->c_kids;
- config_build_schema_inc( &c, ce, op, &rs );
+ if (config_build_schema_inc( &c, ce, op, &rs )) {
+ return -1;
+ }
}
/* Create backend nodes. Skip if they don't provide a cf_table.
c.bi = bi;
e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_BACKEND,
bi->bi_cf_ocs );
+ if ( !e ) {
+ return -1;
+ }
}
/* Create database nodes... */
c.bi = bi;
e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_DATABASE,
be->be_cf_ocs );
+ if ( !e ) {
+ return -1;
+ }
ce = e->e_private;
if ( be->be_cf_ocs && be->be_cf_ocs->co_cfadd )
be->be_cf_ocs->co_cfadd( op, &rs, e, &c );
c.bi = &on->on_bi;
oe = config_build_entry( op, &rs, ce, &c, &rdn,
&CFOC_OVERLAY, c.bi->bi_cf_ocs );
+ if ( !oe ) {
+ return -1;
+ }
if ( c.bi->bi_cf_ocs && c.bi->bi_cf_ocs->co_cfadd )
c.bi->bi_cf_ocs->co_cfadd( op, &rs, oe, &c );
}
NULL
};
+ /* Make sure we don't exceed the bits reserved for userland */
+ config_check_userland( CFG_LAST );
+
bi->bi_controls = controls;
bi->bi_open = 0;
bi->bi_chk_referrals = 0;
-#ifdef SLAP_OVERLAY_ACCESS
bi->bi_access_allowed = slap_access_always_allowed;
-#endif /* SLAP_OVERLAY_ACCESS */
bi->bi_connection_init = 0;
bi->bi_connection_destroy = 0;
bi->bi_tool_entry_get = config_tool_entry_get;
bi->bi_tool_entry_put = config_tool_entry_put;
- /* Make sure we don't exceed the bits reserved for userland */
- assert( ( ( CFG_LAST - 1 ) & ARGS_USERLAND ) == ( CFG_LAST - 1 ) );
-
argv[3] = NULL;
for (i=0; OidMacros[i].name; i++ ) {
argv[1] = OidMacros[i].name;