]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/bconfig.c
fix typo
[openldap] / servers / slapd / bconfig.c
index 0a952f91bddce74719f5a5935b4bcc40a2e1db87..60dd39362dccd71156d3950dd7a0d7b8463afa0a 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2005-2007 The OpenLDAP Foundation.
+ * Copyright 2005-2008 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -189,8 +189,8 @@ typedef struct {
 } OidRec;
 
 static OidRec OidMacros[] = {
-       /* OpenLDAProot:666.11.1 */
-       { "OLcfg", "1.3.6.1.4.1.4203.666.11.1" },
+       /* OpenLDAProot:1.12.2 */
+       { "OLcfg", "1.3.6.1.4.1.4203.1.12.2" },
        { "OLcfgAt", "OLcfg:3" },
        { "OLcfgGlAt", "OLcfgAt:0" },
        { "OLcfgBkAt", "OLcfgAt:1" },
@@ -230,6 +230,7 @@ static OidRec OidMacros[] = {
  * OLcfg{Bk|Db}{Oc|At}:4               -> back-monitor
  * OLcfg{Bk|Db}{Oc|At}:5               -> back-relay
  * OLcfg{Bk|Db}{Oc|At}:6               -> back-sql
+ * OLcfg{Bk|Db}{Oc|At}:7               -> back-sock
  */
 
 /*
@@ -253,6 +254,7 @@ static OidRec OidMacros[] = {
  * OLcfgOv{Oc|At}:17                   -> dyngroup
  * OLcfgOv{Oc|At}:18                   -> memberof
  * OLcfgOv{Oc|At}:19                   -> collect
+ * OLcfgOv{Oc|At}:20                   -> retcode
  */
 
 /* alphabetical ordering */
@@ -500,6 +502,7 @@ static ConfigTable config_back_cf_table[] = {
                        "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
        { "rootdn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
                &config_rootdn, "( OLcfgDbAt:0.8 NAME 'olcRootDN' "
+                       "EQUALITY distinguishedNameMatch "
                        "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
        { "rootDSE", "file", 2, 2, 0, ARG_MAGIC|CFG_ROOTDSE,
                &config_generic, "( OLcfgGlAt:51 NAME 'olcRootDSE' "
@@ -540,6 +543,7 @@ static ConfigTable config_back_cf_table[] = {
                &config_generic, NULL, NULL, NULL },
        { "schemadn", "dn", 2, 2, 0, ARG_MAY_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
                &config_schema_dn, "( OLcfgGlAt:58 NAME 'olcSchemaDN' "
+                       "EQUALITY distinguishedNameMatch "
                        "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
        { "security", "factors", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
                &config_security, "( OLcfgGlAt:59 NAME 'olcSecurity' "
@@ -797,6 +801,11 @@ typedef struct ServerID {
 
 static ServerID *sid_list;
 
+typedef struct voidList {
+       struct voidList *vl_next;
+       void *vl_ptr;
+} voidList;
+
 typedef struct ADlist {
        struct ADlist *al_next;
        AttributeDescription *al_desc;
@@ -883,7 +892,7 @@ config_generic(ConfigArgs *c) {
                        }
                        break;
                case CFG_OID: {
-                       ConfigFile *cf = c->private;
+                       ConfigFile *cf = c->ca_private;
                        if ( !cf )
                                oidm_unparse( &c->rvalue_vals, NULL, NULL, 1 );
                        else if ( cf->c_om_head )
@@ -897,7 +906,7 @@ config_generic(ConfigArgs *c) {
                        ad_unparse_options( &c->rvalue_vals );
                        break;
                case CFG_OC: {
-                       ConfigFile *cf = c->private;
+                       ConfigFile *cf = c->ca_private;
                        if ( !cf )
                                oc_unparse( &c->rvalue_vals, NULL, NULL, 1 );
                        else if ( cf->c_oc_head )
@@ -908,7 +917,7 @@ config_generic(ConfigArgs *c) {
                        }
                        break;
                case CFG_ATTR: {
-                       ConfigFile *cf = c->private;
+                       ConfigFile *cf = c->ca_private;
                        if ( !cf )
                                at_unparse( &c->rvalue_vals, NULL, NULL, 1 );
                        else if ( cf->c_at_head )
@@ -919,7 +928,7 @@ config_generic(ConfigArgs *c) {
                        }
                        break;
                case CFG_DIT: {
-                       ConfigFile *cf = c->private;
+                       ConfigFile *cf = c->ca_private;
                        if ( !cf )
                                cr_unparse( &c->rvalue_vals, NULL, NULL, 1 );
                        else if ( cf->c_cr_head )
@@ -934,7 +943,12 @@ config_generic(ConfigArgs *c) {
                        AccessControl *a;
                        char *src, *dst, ibuf[11];
                        struct berval bv, abv;
-                       for (i=0, a=c->be->be_acl; a; i++,a=a->acl_next) {
+                       AccessControl *end;
+                       if ( c->be == frontendDB )
+                               end = NULL;
+                       else
+                               end = frontendDB->be_acl;
+                       for (i=0, a=c->be->be_acl; a && a != end; i++,a=a->acl_next) {
                                abv.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
                                if ( abv.bv_len >= sizeof( ibuf ) ) {
                                        ber_bvarray_free_x( c->rvalue_vals, NULL );
@@ -962,7 +976,7 @@ config_generic(ConfigArgs *c) {
                        break;
                }
                case CFG_ROOTDSE: {
-                       ConfigFile *cf = c->private;
+                       ConfigFile *cf = c->ca_private;
                        if ( cf->c_dseFiles ) {
                                value_add( &c->rvalue_vals, cf->c_dseFiles );
                        } else {
@@ -1031,7 +1045,7 @@ config_generic(ConfigArgs *c) {
                        } break;
 #ifdef SLAPD_MODULES
                case CFG_MODLOAD: {
-                       ModPaths *mp = c->private;
+                       ModPaths *mp = c->ca_private;
                        if (mp->mp_loads) {
                                int i;
                                for (i=0; !BER_BVISNULL(&mp->mp_loads[i]); i++) {
@@ -1053,7 +1067,7 @@ config_generic(ConfigArgs *c) {
                        }
                        break;
                case CFG_MODPATH: {
-                       ModPaths *mp = c->private;
+                       ModPaths *mp = c->ca_private;
                        if ( !BER_BVISNULL( &mp->mp_path ))
                                value_add_one( &c->rvalue_vals, &mp->mp_path );
 
@@ -1160,6 +1174,8 @@ config_generic(ConfigArgs *c) {
 
                case CFG_IX_INTLEN:
                        index_intlen = SLAP_INDEX_INTLEN_DEFAULT;
+                       index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
+                               SLAP_INDEX_INTLEN_DEFAULT );
                        break;
 
                case CFG_ACL:
@@ -1196,7 +1212,7 @@ config_generic(ConfigArgs *c) {
                                        return 1;
                                }
                        }
-                       cfn = c->private;
+                       cfn = c->ca_private;
                        if ( c->valx < 0 ) {
                                ObjectClass *oc;
 
@@ -1234,7 +1250,7 @@ config_generic(ConfigArgs *c) {
                                        return 1;
                                }
                        }
-                       cfn = c->private;
+                       cfn = c->ca_private;
                        if ( c->valx < 0 ) {
                                AttributeType *at;
 
@@ -1414,8 +1430,8 @@ config_generic(ConfigArgs *c) {
                case CFG_OID: {
                        OidMacro *om;
 
-                       if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
-                               cfn = c->private;
+                       if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+                               cfn = c->ca_private;
                        if(parse_oidm(c, 1, &om))
                                return(1);
                        if (!cfn->c_om_head) cfn->c_om_head = om;
@@ -1426,8 +1442,8 @@ config_generic(ConfigArgs *c) {
                case CFG_OC: {
                        ObjectClass *oc, *prev;
 
-                       if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
-                               cfn = c->private;
+                       if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+                               cfn = c->ca_private;
                        if ( c->valx < 0 ) {
                                prev = cfn->c_oc_tail;
                        } else {
@@ -1458,8 +1474,8 @@ config_generic(ConfigArgs *c) {
                case CFG_ATTR: {
                        AttributeType *at, *prev;
 
-                       if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
-                               cfn = c->private;
+                       if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+                               cfn = c->ca_private;
                        if ( c->valx < 0 ) {
                                prev = cfn->c_at_tail;
                        } else {
@@ -1490,8 +1506,8 @@ config_generic(ConfigArgs *c) {
                case CFG_DIT: {
                        ContentRule *cr;
 
-                       if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
-                               cfn = c->private;
+                       if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+                               cfn = c->ca_private;
                        if(parse_cr(c, &cr)) return(1);
                        if (!cfn->c_cr_head) cfn->c_cr_head = cr;
                        cfn->c_cr_tail = cr;
@@ -1511,6 +1527,8 @@ config_generic(ConfigArgs *c) {
                        else if ( c->value_int > 255 )
                                c->value_int = 255;
                        index_intlen = c->value_int;
+                       index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
+                               index_intlen );
                        break;
                        
                case CFG_SORTVALS: {
@@ -1585,8 +1603,8 @@ sortval_reject:
                        {
                                struct berval bv;
                                ber_str2bv( c->argv[1], 0, 1, &bv );
-                               if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
-                                       cfn = c->private;
+                               if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+                                       cfn = c->ca_private;
                                ber_bvarray_add( &cfn->c_dseFiles, &bv );
                        }
                        break;
@@ -1661,7 +1679,7 @@ sortval_reject:
                                                Listener **l = slapd_get_listeners();
                                                int i;
 
-                                               for ( i=0; l[i]; i++ ) {
+                                               for ( i=0; l && l[i]; i++ ) {
                                                        LDAPURLDesc *lu2;
                                                        int isMe = 0;
                                                        ldap_url_parse( l[i]->sl_url.bv_val, &lu2 );
@@ -1780,8 +1798,8 @@ sortval_reject:
                        /* If we're just adding a module on an existing modpath,
                         * make sure we've selected the current path.
                         */
-                       if ( c->op == LDAP_MOD_ADD && c->private && modcur != c->private ) {
-                               modcur = c->private;
+                       if ( c->op == LDAP_MOD_ADD && c->ca_private && modcur != c->ca_private ) {
+                               modcur = c->ca_private;
                                /* This should never fail */
                                if ( module_path( modcur->mp_path.bv_val )) {
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> module path no longer valid",
@@ -1829,7 +1847,7 @@ sortval_reject:
                                mp->mp_next = NULL;
                                mp->mp_loads = NULL;
                                modlast = mp;
-                               c->private = mp;
+                               c->ca_private = mp;
                                modcur = mp;
                        }
                        
@@ -1888,8 +1906,8 @@ sortval_reject:
 static int
 config_fname(ConfigArgs *c) {
        if(c->op == SLAP_CONFIG_EMIT) {
-               if (c->private) {
-                       ConfigFile *cf = c->private;
+               if (c->ca_private) {
+                       ConfigFile *cf = c->ca_private;
                        value_add_one( &c->rvalue_vals, &cf->c_file );
                        return 0;
                }
@@ -2125,13 +2143,13 @@ config_overlay(ConfigArgs *c) {
                assert(0);
        }
        if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1],
-               c->valx, &c->bi)) {
+               c->valx, &c->bi, &c->reply)) {
                /* log error */
                Debug( LDAP_DEBUG_ANY,
                        "%s: (optional) %s overlay \"%s\" configuration failed.\n",
                        c->log, c->be == frontendDB ? "global " : "", &c->argv[1][1]);
                return 1;
-       } else if(overlay_config(c->be, c->argv[1], c->valx, &c->bi)) {
+       } else if(overlay_config(c->be, c->argv[1], c->valx, &c->bi, &c->reply)) {
                return(1);
        }
        return(0);
@@ -3030,7 +3048,7 @@ config_include(ConfigArgs *c) {
                ch_free( cf->c_file.bv_val );
                ch_free( cf );
        } else {
-               c->private = cf;
+               c->ca_private = cf;
        }
        return(rc);
 }
@@ -3864,7 +3882,7 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
                if ( isconfig && index == -1 ) {
                        index = 0;
                }
-               if ( !isfrontend && index == -1 ) {
+               if (( !isfrontend && index == -1 ) || ( index > nsibs ) ){
                        index = nsibs;
                }
 
@@ -3955,14 +3973,14 @@ cfAddSchema( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
        /* This entry is hardcoded, don't re-parse it */
        if ( p->ce_type == Cft_Global ) {
                cfn = p->ce_private;
-               ca->private = cfn;
+               ca->ca_private = cfn;
                return LDAP_COMPARE_TRUE;
        }
        if ( p->ce_type != Cft_Schema )
                return LDAP_CONSTRAINT_VIOLATION;
 
        cfn = ch_calloc( 1, sizeof(ConfigFile) );
-       ca->private = cfn;
+       ca->ca_private = cfn;
        cfo = p->ce_private;
        cfn->c_sibs = cfo->c_kids;
        cfo->c_kids = cfn;
@@ -3975,6 +3993,11 @@ cfAddDatabase( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
        if ( p->ce_type != Cft_Global ) {
                return LDAP_CONSTRAINT_VIOLATION;
        }
+       /* config must be {0}, nothing else allowed */
+       if ( !strncmp( e->e_nname.bv_val, "olcDatabase={0}", STRLENOF("olcDatabase={0}")) &&
+               strncmp( e->e_nname.bv_val + STRLENOF("olcDatabase={0}"), "config,", STRLENOF("config,") )) {
+               return LDAP_CONSTRAINT_VIOLATION;
+       }
        ca->be = frontendDB;    /* just to get past check_vals */
        return LDAP_SUCCESS;
 }
@@ -4214,7 +4237,7 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
        rc = LDAP_CONSTRAINT_VIOLATION;
        if ( coptr->co_type == Cft_Global && !last ) {
                cfn = cfb->cb_config;
-               ca->private = cfn;
+               ca->ca_private = cfn;
                ca->be = frontendDB;    /* just to get past check_vals */
                rc = LDAP_SUCCESS;
        }
@@ -4367,7 +4390,7 @@ ok:
        ce->ce_type = colst[0]->co_type;
        ce->ce_be = ca->be;
        ce->ce_bi = ca->bi;
-       ce->ce_private = ca->private;
+       ce->ce_private = ca->ca_private;
        ca->ca_entry = ce->ce_entry;
        if ( !last ) {
                cfb->cb_root = ce;
@@ -4650,7 +4673,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
        init_config_argv( ca );
        ca->be = ce->ce_be;
        ca->bi = ce->ce_bi;
-       ca->private = ce->ce_private;
+       ca->ca_private = ce->ce_private;
        ca->ca_entry = e;
        ca->fname = "slapd";
        ca->ca_op = op;
@@ -4765,8 +4788,9 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
                /* check that the entry still obeys the schema */
                rc = entry_schema_check(op, e, NULL, 0, 0,
                        &rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg) );
-               if ( rc ) goto out_noop;
        }
+       if ( rc ) goto out_noop;
+
        /* Basic syntax checks are OK. Do the actual settings. */
        for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
                ct = config_find_table( colst, nocs, ml->sml_desc, ca );
@@ -5209,7 +5233,102 @@ out:
 static int
 config_back_delete( Operation *op, SlapReply *rs )
 {
-       send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, NULL );
+#ifdef SLAP_CONFIG_DELETE
+       CfBackInfo *cfb;
+       CfEntryInfo *ce, *last, *ce2;
+
+       cfb = (CfBackInfo *)op->o_bd->be_private;
+
+       ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
+       if ( !ce ) {
+               if ( last )
+                       rs->sr_matched = last->ce_entry->e_name.bv_val;
+               rs->sr_err = LDAP_NO_SUCH_OBJECT;
+       } else if ( ce->ce_kids ) {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+       } else if ( ce->ce_type == Cft_Overlay || ce->ce_type == Cft_Database ){
+               char *iptr;
+               int count, ixold;
+
+               ldap_pvt_thread_pool_pause( &connection_pool );
+
+               if ( ce->ce_type == Cft_Overlay ){
+                       overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi );
+               } else { /* Cft_Database*/
+                       if ( ce->ce_be == frontendDB || ce->ce_be == op->o_bd ){
+                               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+                               rs->sr_text = "Cannot delete config or frontend database";
+                               ldap_pvt_thread_pool_resume( &connection_pool );
+                               goto out;
+                       } 
+                       if ( ce->ce_be->bd_info->bi_db_close ) {
+                               ce->ce_be->bd_info->bi_db_close( ce->ce_be, NULL );
+                       }
+                       backend_destroy_one( ce->ce_be, 1);
+               }
+
+               /* remove CfEntryInfo from the siblings list */
+               if ( ce->ce_parent->ce_kids == ce ) {
+                       ce->ce_parent->ce_kids = ce->ce_sibs;
+               } else {
+                       for ( ce2 = ce->ce_parent->ce_kids ; ce2; ce2 = ce2->ce_sibs ) {
+                               if ( ce2->ce_sibs == ce ) {
+                                       ce2->ce_sibs = ce->ce_sibs;
+                                       break;
+                               }
+                       }
+               }
+
+               /* remove from underlying database */
+               if ( cfb->cb_use_ldif ) {
+                       BackendDB *be = op->o_bd;
+                       slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
+                       struct berval dn, ndn, req_dn, req_ndn;
+
+                       op->o_bd = &cfb->cb_db;
+
+                       dn = op->o_dn;
+                       ndn = op->o_ndn;
+                       req_dn = op->o_req_dn;
+                       req_ndn = op->o_req_ndn;
+
+                       op->o_dn = op->o_bd->be_rootdn;
+                       op->o_ndn = op->o_bd->be_rootndn;
+                       op->o_req_dn = ce->ce_entry->e_name;
+                       op->o_req_ndn = ce->ce_entry->e_nname;
+
+                       scp = op->o_callback;
+                       op->o_callback = &sc;
+                       op->o_bd->be_delete( op, rs );
+                       op->o_bd = be;
+                       op->o_callback = scp;
+                       op->o_dn = dn;
+                       op->o_ndn = ndn;
+                       op->o_req_dn = req_dn;
+                       op->o_req_ndn = req_ndn;
+               }
+
+               /* renumber siblings */
+               iptr = ber_bvchr( &op->o_req_ndn, '{' ) + 1;
+               ixold = strtol( iptr, NULL, 0 );
+               for (ce2 = ce->ce_sibs, count=0; ce2; ce2=ce2->ce_sibs) {
+                       config_renumber_one( op, rs, ce2->ce_parent, ce2->ce_entry,
+                               count+ixold, 0, cfb->cb_use_ldif );
+                       count++;
+               }
+
+               ce->ce_entry->e_private=NULL;
+               entry_free(ce->ce_entry);
+               ch_free(ce);
+               ldap_pvt_thread_pool_resume( &connection_pool );
+       } else {
+               rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+       }
+#else
+       rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+#endif /* SLAP_CONFIG_DELETE */
+out:
+       send_ldap_result( op, rs );
        return rs->sr_err;
 }
 
@@ -5282,18 +5401,23 @@ int config_back_entry_get(
 {
        CfBackInfo *cfb;
        CfEntryInfo *ce, *last;
+       int rc = LDAP_NO_SUCH_OBJECT;
 
        cfb = (CfBackInfo *)op->o_bd->be_private;
 
        ce = config_find_base( cfb->cb_root, ndn, &last );
        if ( ce ) {
                *ent = ce->ce_entry;
-               if ( *ent && oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
-                       *ent = NULL;
+               if ( *ent ) {
+                       rc = LDAP_SUCCESS;
+                       if ( oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
+                               rc = LDAP_NO_SUCH_ATTRIBUTE;
+                               *ent = NULL;
+                       }
                }
        }
 
-       return ( *ent == NULL ? 1 : 0 );
+       return rc;
 }
 
 static void
@@ -5351,7 +5475,7 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
        ce->ce_parent = parent;
        if ( parent ) {
                pdn = parent->ce_entry->e_nname;
-               if ( parent->ce_kids )
+               if ( parent->ce_kids && parent->ce_kids->ce_type <= ce->ce_type )
                        for ( ceprev = parent->ce_kids; ceprev->ce_sibs &&
                                ceprev->ce_type <= ce->ce_type;
                                ceprev = ceprev->ce_sibs );
@@ -5359,7 +5483,7 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
                BER_BVZERO( &pdn );
        }
 
-       ce->ce_private = c->private;
+       ce->ce_private = c->ca_private;
        ce->ce_be = c->be;
        ce->ce_bi = c->bi;
 
@@ -5403,14 +5527,23 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
        oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
        rc = structural_class(oc_at->a_vals, &oc, NULL, &text, c->cr_msg,
                sizeof(c->cr_msg), op ? op->o_tmpmemctx : NULL );
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "config_build_entry: build \"%s\" failed: \"%s\"\n",
+                       rdn->bv_val, text, 0);
+               return NULL;
+       }
        attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &oc->soc_cname, NULL );
-       if ( op && !op->o_noop ) {
+       if ( op ) {
                op->ora_e = e;
                op->ora_modlist = NULL;
-               op->o_bd->be_add( op, rs );
-               if ( ( rs->sr_err != LDAP_SUCCESS ) 
-                               && (rs->sr_err != LDAP_ALREADY_EXISTS) ) {
-                       return NULL;
+               slap_add_opattrs( op, NULL, NULL, 0, 0 );
+               if ( !op->o_noop ) {
+                       op->o_bd->be_add( op, rs );
+                       if ( ( rs->sr_err != LDAP_SUCCESS ) 
+                                       && (rs->sr_err != LDAP_ALREADY_EXISTS) ) {
+                               return NULL;
+                       }
                }
        }
        if ( ceprev ) {
@@ -5429,7 +5562,7 @@ config_build_schema_inc( ConfigArgs *c, CfEntryInfo *ceparent,
        Operation *op, SlapReply *rs )
 {
        Entry *e;
-       ConfigFile *cf = c->private;
+       ConfigFile *cf = c->ca_private;
        char *ptr;
        struct berval bv;
 
@@ -5458,13 +5591,13 @@ config_build_schema_inc( ConfigArgs *c, CfEntryInfo *ceparent,
                c->value_dn.bv_len += bv.bv_len;
                c->value_dn.bv_val[c->value_dn.bv_len] ='\0';
 
-               c->private = cf;
+               c->ca_private = cf;
                e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
                        &CFOC_SCHEMA, NULL );
                if ( !e ) {
                        return -1;
                } else if ( e && cf->c_kids ) {
-                       c->private = cf->c_kids;
+                       c->ca_private = cf->c_kids;
                        config_build_schema_inc( c, e->e_private, op, rs );
                }
        }
@@ -5489,7 +5622,7 @@ config_build_modules( ConfigArgs *c, CfEntryInfo *ceparent,
                        /* FIXME: how can indicate error? */
                        return -1;
                }
-               c->private = mp;
+               c->ca_private = mp;
                if ( ! config_build_entry( op, rs, ceparent, c, &c->value_dn, &CFOC_MODULE, NULL )) {
                        return -1;
                }
@@ -5566,7 +5699,7 @@ config_check_schema(Operation *op, CfBackInfo *cfb)
                }
        } else {
                SlapReply rs = {REP_RESULT};
-               c.private = NULL;
+               c.ca_private = NULL;
                e = config_build_entry( op, &rs, cfb->cb_root, &c, &schema_rdn,
                        &CFOC_SCHEMA, NULL );
                if ( !e ) {
@@ -5632,7 +5765,7 @@ config_back_db_open( BackendDB *be, ConfigReply *cr )
 
        /* create root of tree */
        rdn = config_rdn;
-       c.private = cfb->cb_config;
+       c.ca_private = cfb->cb_config;
        c.be = frontendDB;
        e = config_build_entry( op, &rs, NULL, &c, &rdn, &CFOC_GLOBAL, NULL );
        if ( !e ) {
@@ -5658,7 +5791,7 @@ config_back_db_open( BackendDB *be, ConfigReply *cr )
         * files.
         */
        rdn = schema_rdn;
-       c.private = NULL;
+       c.ca_private = NULL;
        e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_SCHEMA, NULL );
        if ( !e ) {
                return -1;
@@ -5672,7 +5805,7 @@ config_back_db_open( BackendDB *be, ConfigReply *cr )
        /* Create schema nodes for included schema... */
        if ( cfb->cb_config->c_kids ) {
                c.depth = 0;
-               c.private = cfb->cb_config->c_kids;
+               c.ca_private = cfb->cb_config->c_kids;
                if (config_build_schema_inc( &c, ce, op, &rs )) {
                        return -1;
                }
@@ -5755,8 +5888,19 @@ config_back_db_open( BackendDB *be, ConfigReply *cr )
                        slap_overinst *on;
                        Entry *oe;
                        int j;
-
-                       for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
+                       voidList *vl, *v0 = NULL;
+
+                       /* overlays are in LIFO order, must reverse stack */
+                       for (on=oi->oi_list; on; on=on->on_next) {
+                               vl = ch_malloc( sizeof( voidList ));
+                               vl->vl_next = v0;
+                               v0 = vl;
+                               vl->vl_ptr = on;
+                       }
+                       for (j=0; vl; j++,vl=v0) {
+                               on = vl->vl_ptr;
+                               v0 = vl->vl_next;
+                               ch_free( vl );
                                if ( on->on_bi.bi_db_config && !on->on_bi.bi_cf_ocs ) {
                                        Debug( LDAP_DEBUG_ANY,
                                                "WARNING: No dynamic config support for overlay %s.\n",