#include "slapi/slapi.h"
#endif
+#include <ldif.h>
#include <lutil.h>
#include "config.h"
static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
*cfAd_include;
-static ConfigFile cf_prv, *cfn = &cf_prv;
+static ConfigFile *cfn;
static Avlnode *CfOcTree;
static int
config_search_base(ConfigArgs *c) {
- struct berval dn;
-
if(c->op == SLAP_CONFIG_EMIT) {
int rc = 1;
if (!BER_BVISEMPTY(&default_search_base)) {
/* log error */
Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: (optional) %s overlay \"%s\" configuration failed"
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
- c->log, c->be == frontendDB ? "global " : "", c->argv[1][1]);
+ c->log, c->be == frontendDB ? "global " : "", &c->argv[1][1]);
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
return 1;
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
}
static int
-config_suffix(ConfigArgs *c) {
+config_suffix(ConfigArgs *c)
+{
Backend *tbe;
struct berval pdn, ndn;
- int rc;
+ char *notallowed = NULL;
+
+ if ( c->be == frontendDB ) {
+ notallowed = "frontend";
+
+ } else if ( SLAP_MONITOR(c->be) ) {
+ notallowed = "monitor";
+
+ } else if ( SLAP_CONFIG(c->be) ) {
+ notallowed = "config";
+ }
+
+ if ( notallowed != NULL ) {
+ char buf[ SLAP_TEXT_BUFLEN ] = { '\0' };
+
+ if ( !BER_BVISNULL( &c->value_dn ) ) {
+ snprintf( buf, sizeof( buf ), "<%s> ", c->value_dn.bv_val );
+ }
- if (c->be == frontendDB || SLAP_MONITOR(c->be) ||
- SLAP_CONFIG(c->be)) return 1;
+ Debug(LDAP_DEBUG_ANY,
+ "%s: suffix %snot allowed in %s database.\n",
+ c->log, buf, notallowed );
+ return 1;
+ }
if (c->op == SLAP_CONFIG_EMIT) {
if ( c->be->be_suffix == NULL
}
return 0;
}
+
#ifdef SLAPD_MONITOR_DN
if(!strcasecmp(c->argv[1], SLAPD_MONITOR_DN)) {
sprintf( c->msg, "<%s> DN is reserved for monitoring slapd",
return(0);
}
+static slap_verbmasks *loglevel_ops;
+
static int
-config_loglevel(ConfigArgs *c) {
- int i;
- char *next;
- slap_verbmasks loglevel_ops[] = {
+loglevel_init( void )
+{
+ slap_verbmasks lo[] = {
{ BER_BVC("Any"), -1 },
{ BER_BVC("Trace"), LDAP_DEBUG_TRACE },
{ BER_BVC("Packets"), LDAP_DEBUG_PACKETS },
{ BER_BVNULL, 0 }
};
+ return slap_verbmasks_init( &loglevel_ops, lo );
+}
+
+static slap_mask_t loglevel_ignore[] = { -1, 0 };
+
+int
+slap_loglevel_register( slap_mask_t m, struct berval *s )
+{
+ int rc;
+
+ if ( loglevel_ops == NULL ) {
+ loglevel_init();
+ }
+
+ rc = slap_verbmasks_append( &loglevel_ops, m, s, loglevel_ignore );
+
+ if ( rc != 0 ) {
+ Debug( LDAP_DEBUG_ANY, "slap_loglevel_register(%d, \"%s\") failed\n",
+ m, s->bv_val, 0 );
+ }
+
+ return rc;
+}
+
+static int
+config_loglevel(ConfigArgs *c) {
+ int i;
+ char *next;
+
+ if ( loglevel_ops == NULL ) {
+ loglevel_init();
+ }
+
if (c->op == SLAP_CONFIG_EMIT) {
return mask_to_verbs( loglevel_ops, ldap_syslog, &c->rvalue_vals );
} else if ( c->op == LDAP_MOD_DELETE ) {
for( i=1; i < c->argc; i++ ) {
int level;
- if ( isdigit( c->argv[i][0] ) ) {
+ if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) {
level = strtol( c->argv[i], &next, 10 );
if ( next == NULL || next[0] != '\0' ) {
sprintf( c->msg, "<%s> unable to parse level", c->argv[0] );
static int
config_include(ConfigArgs *c) {
- unsigned long savelineno = c->lineno;
+ int savelineno = c->lineno;
int rc;
ConfigFile *cf;
ConfigFile *cfsave = cfn;
op->o_bd = &cfb->cb_db;
rc = op->o_bd->be_search( op, &rs );
+
+ slap_sl_mem_destroy( NULL, op->o_tmpmemctx );
}
cfb->cb_use_ldif = 1;
rc = read_config_file(cfname, 0, NULL, config_back_cf_table);
if ( rc == 0 )
- ber_str2bv( cfname, 0, 1, &cf_prv.c_file );
+ ber_str2bv( cfname, 0, 1, &cfb->cb_config->c_file );
/* If we got this far and failed, it may be a serious problem. In server
* mode, we should never come to this. However, it may be alright if we're
if ( ca->lineno )
return LDAP_COMPARE_TRUE;
- if ( p->ce_type == Cft_Global )
- cfn = &cf_prv;
- else
- cfn = p->ce_private;
+ cfn = p->ce_private;
ca->private = cfn;
return LDAP_SUCCESS;
}
/* This entry is hardcoded, don't re-parse it */
if ( p->ce_type == Cft_Global ) {
- cfn = &cf_prv;
+ cfn = p->ce_private;
ca->private = cfn;
return LDAP_COMPARE_TRUE;
}
CfEntryInfo *ce, *last;
ConfigOCs **colst;
Attribute *a, *oc_at;
- int i, j, nocs, rc = 0;
+ int i, nocs, rc = 0;
struct berval pdn;
ConfigTable *ct;
char *ptr;
*/
rc = LDAP_CONSTRAINT_VIOLATION;
if ( colst[0]->co_type == Cft_Global && !last ) {
- cfn = &cf_prv;
+ cfn = cfb->cb_config;
ca->private = cfn;
ca->be = frontendDB; /* just to get past check_vals */
rc = LDAP_SUCCESS;
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
ca->log, ca->msg, ca->argv[1] );
rc = LDAP_OTHER;
- if ( colst[0]->co_type == Cft_Database )
- backend_destroy_one( ca->be );
- else
- overlay_destroy_one( ca->be, (slap_overinst *)ca->bi );
goto leave;
}
}
}
leave:
+ if ( rc ) {
+ if ( (colst[0]->co_type == Cft_Database) && ca->be ) {
+ backend_destroy_one( ca->be, 1 );
+ } else if ( (colst[0]->co_type == Cft_Overlay) && ca->bi ) {
+ overlay_destroy_one( ca->be, (slap_overinst *)ca->bi );
+ }
+ }
+
ch_free( ca->argv );
if ( colst ) ch_free( colst );
return rc;
config_back_add( Operation *op, SlapReply *rs )
{
CfBackInfo *cfb;
- CfEntryInfo *ce, *last;
int renumber;
ConfigArgs ca;
config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
ConfigArgs *ca )
{
- CfBackInfo *cfb = (CfBackInfo *)op->o_bd->be_private;
int rc = LDAP_UNWILLING_TO_PERFORM;
Modifications *ml;
Entry *e = ce->ce_entry;
int *idx = NULL;
if ( ct && ( ct->arg_type & ARG_NO_DELETE )) {
rc = LDAP_OTHER;
- snprintf( ca->msg, sizeof(ca->msg),
- "<%s> cannot be deleted" );
snprintf(ca->msg, sizeof(ca->msg), "cannot delete %s",
ml->sml_desc->ad_cname.bv_val );
goto out;
{
CfBackInfo *cfb;
CfEntryInfo *ce, *last;
- int rc;
if ( !be_isroot( op ) ) {
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
CfBackInfo *cfb = be->be_private;
struct berval rdn;
Entry *e, *parent;
- CfEntryInfo *ce, *ceparent, *ceprev;
- int i, rc;
+ CfEntryInfo *ce, *ceparent;
+ int i;
BackendInfo *bi;
BackendDB *bptr;
ConfigArgs c;
- ConfigTable *ct;
Connection conn = {0};
char opbuf[OPERATION_BUFFER_SIZE];
Operation *op;
}
}
}
+ if ( op )
+ slap_sl_mem_destroy( NULL, op->o_tmpmemctx );
return 0;
}
+static void
+cfb_free_cffile( ConfigFile *cf )
+{
+ ConfigFile *next;
+
+ for (; cf; cf=next) {
+ next = cf->c_sibs;
+ if ( cf->c_kids )
+ cfb_free_cffile( cf->c_kids );
+ ch_free( cf->c_file.bv_val );
+ ber_bvarray_free( cf->c_dseFiles );
+ ch_free( cf );
+ }
+}
+
+static void
+cfb_free_entries( CfEntryInfo *ce )
+{
+ CfEntryInfo *next;
+
+ for (; ce; ce=next) {
+ next = ce->ce_sibs;
+ if ( ce->ce_kids )
+ cfb_free_entries( ce->ce_kids );
+ ce->ce_entry->e_private = NULL;
+ entry_free( ce->ce_entry );
+ ch_free( ce );
+ }
+}
+
static int
-config_back_db_destroy( Backend *be )
+config_back_db_close( BackendDB *be )
{
+ CfBackInfo *cfb = be->be_private;
+
+ cfb_free_entries( cfb->cb_root );
+ cfb->cb_root = NULL;
+
+ if ( cfb->cb_db.bd_info ) {
+ backend_shutdown( &cfb->cb_db );
+ }
+
+ return 0;
+}
+
+static int
+config_back_db_destroy( BackendDB *be )
+{
+ CfBackInfo *cfb = be->be_private;
+
+ cfb_free_cffile( cfb->cb_config );
+
+ ch_free( cfdir.bv_val );
+
+ avl_free( CfOcTree, NULL );
+
+ if ( cfb->cb_db.bd_info ) {
+ cfb->cb_db.be_suffix = NULL;
+ cfb->cb_db.be_nsuffix = NULL;
+ BER_BVZERO( &cfb->cb_db.be_rootdn );
+ BER_BVZERO( &cfb->cb_db.be_rootndn );
+
+ backend_destroy_one( &cfb->cb_db, 0 );
+ }
+
free( be->be_private );
+
return 0;
}
static int
-config_back_db_init( Backend *be )
+config_back_db_init( BackendDB *be )
{
struct berval dn;
CfBackInfo *cfb;
cfb = ch_calloc( 1, sizeof(CfBackInfo));
- cfb->cb_config = &cf_prv;
+ cfb->cb_config = ch_calloc( 1, sizeof(ConfigFile));
+ cfn = cfb->cb_config;
be->be_private = cfb;
ber_dupbv( &be->be_rootdn, &config_rdn );
bi->bi_db_init = config_back_db_init;
bi->bi_db_config = 0;
bi->bi_db_open = config_back_db_open;
- bi->bi_db_close = 0;
+ bi->bi_db_close = config_back_db_close;
bi->bi_db_destroy = config_back_db_destroy;
bi->bi_op_bind = config_back_bind;