]> git.sur5r.net Git - openldap/commitdiff
Restructured to allow miscellaneous Adds under database/overlay objects
authorHoward Chu <hyc@openldap.org>
Mon, 9 May 2005 03:42:51 +0000 (03:42 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 9 May 2005 03:42:51 +0000 (03:42 +0000)
servers/slapd/back-bdb/config.c
servers/slapd/back-bdb/init.c
servers/slapd/back-ldif/ldif.c
servers/slapd/bconfig.c
servers/slapd/config.c
servers/slapd/config.h
servers/slapd/slap.h

index 063f10134bcf3154bbadafa614532cfe5831729f..f8254e98f42d5213ed163069ec2e1424dba44f7c 100644 (file)
@@ -38,7 +38,7 @@
 
 static ObjectClass *bdb_oc;
 
-static ConfigDriver bdb_cf_oc, bdb_cf_gen;
+static ConfigDriver bdb_cf_gen;
 
 enum {
        BDB_CHKPT = 1,
@@ -52,8 +52,6 @@ enum {
 };
 
 static ConfigTable bdbcfg[] = {
-       { "", "", 0, 0, 0, ARG_MAGIC,
-               bdb_cf_oc, NULL, NULL, NULL },
        { "directory", "dir", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_DIRECTORY,
                bdb_cf_gen, "( OLcfgDbAt:0.1 NAME 'olcDbDirectory' "
                        "DESC 'Directory for database content' "
@@ -132,7 +130,7 @@ static ConfigOCs bdbocs[] = {
                "olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ "
                "olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ "
                "olcDbMode $ olcDbSearchStack $ olcDbShmKey ) )",
-                       Cft_Database, &bdb_oc },
+                       Cft_Database, &bdb_oc, bdbcfg },
        { NULL, 0, NULL }
 };
 
@@ -617,10 +615,9 @@ bdb_cf_gen(ConfigArgs *c)
 int bdb_back_init_cf( BackendInfo *bi )
 {
        int rc;
-       bi->bi_cf_table = bdbcfg;
+       bi->bi_cf_ocs = bdbocs;
 
        rc = config_register_schema( bdbcfg, bdbocs );
        if ( rc ) return rc;
-       bdbcfg[0].ad = slap_schema.si_ad_objectClass;
        return 0;
 }
index 84ecfe3087203857fead0b3a9cc48c054431d9a1..b63961f027b19353fdea6fb262178d1094685edd 100644 (file)
@@ -71,7 +71,7 @@ bdb_db_init( BackendDB *be )
        ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
 
        be->be_private = bdb;
-       be->be_cf_table = be->bd_info->bi_cf_table;
+       be->be_cf_ocs = be->bd_info->bi_cf_ocs;
 
        return 0;
 }
index 5ac20b94480e72c9b5f1bf048c559bf8e3a2c842..417a4d90d41f3340e7560d08766cc461317dcdb9 100644 (file)
@@ -63,11 +63,7 @@ struct ldif_info {
 
 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),
                "( OLcfgDbAt:0.1 NAME 'olcDbDirectory' "
@@ -84,20 +80,10 @@ static ConfigOCs ldifocs[] = {
                "DESC 'LDIF backend configuration' "
                "SUP olcDatabaseConfig "
                "MUST ( olcDbDirectory ) )", Cft_Database,
-               &ldif_oc },
+               &ldif_oc, ldifcfg },
        { NULL, 0, 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 void
 dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path,
        struct berval *res)
@@ -1169,7 +1155,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;
+       be->be_cf_ocs = ldifocs;
        ldap_pvt_thread_mutex_init(&ni->li_mutex);
        return 0;
 }
@@ -1214,8 +1200,6 @@ ldif_back_initialize(
 
        bi->bi_controls = controls;
 
-       bi->bi_cf_table = ldifcfg;
-
        bi->bi_open = 0;
        bi->bi_close = 0;
        bi->bi_config = 0;
@@ -1259,6 +1243,5 @@ ldif_back_initialize(
 
        rc = config_register_schema( ldifcfg, ldifocs );
        if ( rc ) return rc;
-       ldifcfg[0].ad = slap_schema.si_ad_objectClass;
        return 0;
 }
index 49ef640e9db19317fef6a5a7a2555e61121c6fc7..eb7071ea109d8f7802f656ef38ee894cfe15da6d 100644 (file)
@@ -62,24 +62,6 @@ typedef struct ConfigFile {
        BerVarray c_dseFiles;
 } ConfigFile;
 
-typedef struct CfOcInfo {
-       struct berval *co_name;
-       ConfigTable *co_table;
-       ConfigType co_type;
-       ObjectClass *co_oc;
-} CfOcInfo;
-
-typedef struct CfEntryInfo {
-       struct CfEntryInfo *ce_parent;
-       struct CfEntryInfo *ce_sibs;
-       struct CfEntryInfo *ce_kids;
-       Entry *ce_entry;
-       ConfigType ce_type;
-       BackendInfo *ce_bi;
-       BackendDB *ce_be;
-       void *ce_private;
-} CfEntryInfo;
-
 typedef struct {
        ConfigFile *cb_config;
        CfEntryInfo *cb_root;
@@ -218,7 +200,7 @@ static OidRec OidMacros[] = {
 
 /* alphabetical ordering */
 
-ConfigTable config_back_cf_table[] = {
+static ConfigTable config_back_cf_table[] = {
        /* This attr is read-only */
        { "", "", 0, 0, 0, ARG_MAGIC,
                &config_fname, "( OLcfgGlAt:78 NAME 'olcConfigFile' "
@@ -590,6 +572,18 @@ ConfigTable config_back_cf_table[] = {
                NULL, NULL, NULL, NULL }
 };
 
+/* Routines to check if a child can be added to this type */
+static ConfigLDAPadd cfAddSchema, cfAddInclude, cfAddDatabase,
+       cfAddBackend, cfAddModule, cfAddOverlay;
+
+#define CFOC_GLOBAL    cf_ocs[1]
+#define CFOC_SCHEMA    cf_ocs[2]
+#define CFOC_BACKEND   cf_ocs[3]
+#define CFOC_DATABASE  cf_ocs[4]
+#define CFOC_OVERLAY   cf_ocs[5]
+#define CFOC_INCLUDE   cf_ocs[6]
+#define CFOC_MODULE    cf_ocs[7]
+
 static ConfigOCs cf_ocs[] = {
        { "( OLcfgGlOc:1 "
                "NAME 'olcConfig' "
@@ -627,12 +621,12 @@ static ConfigOCs cf_ocs[] = {
                "SUP olcConfig STRUCTURAL "
                "MAY ( cn $ olcObjectIdentifier $ olcAttributeTypes $ "
                 "olcObjectClasses $ olcDitContentRules ) )",
-                       Cft_Schema, &cfOc_schema },
+                       Cft_Schema, &cfOc_schema, NULL, cfAddSchema },
        { "( OLcfgGlOc:4 "
                "NAME 'olcBackendConfig' "
                "DESC 'OpenLDAP Backend-specific options' "
                "SUP olcConfig STRUCTURAL "
-               "MUST olcBackend )", Cft_Backend, &cfOc_backend },
+               "MUST olcBackend )", Cft_Backend, &cfOc_backend, NULL, cfAddBackend },
        { "( OLcfgGlOc:5 "
                "NAME 'olcDatabaseConfig' "
                "DESC 'OpenLDAP Database-specific options' "
@@ -643,26 +637,26 @@ static ConfigOCs cf_ocs[] = {
                 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
                 "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
                 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef ) )",
-                       Cft_Database, &cfOc_database },
+                       Cft_Database, &cfOc_database, NULL, cfAddDatabase },
        { "( OLcfgGlOc:6 "
                "NAME 'olcOverlayConfig' "
                "DESC 'OpenLDAP Overlay-specific options' "
                "SUP olcConfig STRUCTURAL "
-               "MUST olcOverlay )", Cft_Overlay, &cfOc_overlay },
+               "MUST olcOverlay )", Cft_Overlay, &cfOc_overlay, NULL, cfAddOverlay },
        { "( OLcfgGlOc:7 "
                "NAME 'olcIncludeFile' "
                "DESC 'OpenLDAP configuration include file' "
                "SUP olcConfig STRUCTURAL "
                "MUST olcInclude "
                "MAY ( cn $ olcRootDSE ) )",
-               Cft_Include, &cfOc_include },
+               Cft_Include, &cfOc_include, NULL, cfAddInclude },
 #ifdef SLAPD_MODULES
        { "( OLcfgGlOc:8 "
                "NAME 'olcModuleList' "
                "DESC 'OpenLDAP dynamic module info' "
                "SUP olcConfig STRUCTURAL "
                "MUST ( olcModulePath $ olcModuleLoad ) "
-               "MAY cn )", Cft_Module, &cfOc_module },
+               "MAY cn )", Cft_Module, &cfOc_module, NULL, cfAddModule },
 #endif
        { NULL, 0, NULL }
 };
@@ -2266,7 +2260,7 @@ config_include(ConfigArgs *c) {
        }
        cfn = cf;
        ber_str2bv( c->argv[1], 0, 1, &cf->c_file );
-       rc = read_config_file(c->argv[1], c->depth + 1, c);
+       rc = read_config_file(c->argv[1], c->depth + 1, c, config_back_cf_table);
        c->lineno = savelineno - 1;
        cfn = cfsave;
        if ( rc ) {
@@ -2452,7 +2446,7 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
        argv[2] = NULL;
        c.argv = argv;
 
-       ct = config_find_keyword( c.be->be_cf_table, &c );
+       ct = config_find_keyword( c.be->be_cf_ocs->co_table, &c );
        if ( !ct )
                return 1;
 
@@ -2499,9 +2493,9 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
 }
 
 static int
-CfOcInfo_cmp( const void *c1, const void *c2 ) {
-       const CfOcInfo *co1 = c1;
-       const CfOcInfo *co2 = c2;
+CfOc_cmp( const void *c1, const void *c2 ) {
+       const ConfigOCs *co1 = c1;
+       const ConfigOCs *co2 = c2;
 
        return ber_bvcmp( co1->co_name, co2->co_name );
 }
@@ -2509,7 +2503,6 @@ CfOcInfo_cmp( const void *c1, const void *c2 ) {
 int
 config_register_schema(ConfigTable *ct, ConfigOCs *ocs) {
        int i;
-       CfOcInfo *co;
 
        i = init_config_attrs( ct );
        if ( i ) return i;
@@ -2518,14 +2511,12 @@ config_register_schema(ConfigTable *ct, ConfigOCs *ocs) {
        i = init_config_ocs( ocs );
        if ( i ) return i;
 
-       for (i=0; ocs[i].def; i++) {
-               if ( ocs[i].oc ) {
-                       co = ch_malloc( sizeof(CfOcInfo) );
-                       co->co_oc = *ocs[i].oc;
-                       co->co_name = &co->co_oc->soc_cname;
-                       co->co_table = ct;
-                       co->co_type = ocs[i].cft;
-                       avl_insert( &CfOcTree, co, CfOcInfo_cmp, avl_dup_error );
+       for (i=0; ocs[i].co_def; i++) {
+               if ( ocs[i].co_oc ) {
+                       ocs[i].co_name = &((*ocs[i].co_oc)->soc_cname);
+                       if ( !ocs[i].co_table )
+                               ocs[i].co_table = ct;
+                       avl_insert( &CfOcTree, &ocs[i], CfOc_cmp, avl_dup_error );
                }
        }
        return 0;
@@ -2575,7 +2566,7 @@ read_config(const char *fname, const char *dir) {
        else
                cfname = SLAPD_DEFAULT_CONFIGFILE;
 
-       rc = read_config_file(cfname, 0, NULL);
+       rc = read_config_file(cfname, 0, NULL, config_back_cf_table);
 
        if ( rc == 0 )
                ber_str2bv( cfname, 0, 1, &cf_prv.c_file );
@@ -2643,7 +2634,7 @@ config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
 }
 
 static ConfigTable *
-config_find_table( CfOcInfo **colst, int nocs, AttributeDescription *ad )
+config_find_table( ConfigOCs **colst, int nocs, AttributeDescription *ad )
 {
        int i, j;
 
@@ -2662,14 +2653,14 @@ config_find_table( CfOcInfo **colst, int nocs, AttributeDescription *ad )
  * list the attributes in the desired sequence.
  */
 static void
-sort_attrs( Entry *e, CfOcInfo **colst, int nocs )
+sort_attrs( Entry *e, ConfigOCs **colst, int nocs )
 {
        Attribute *a, *head = NULL, *tail = NULL, **prev;
        int i, j;
 
        for (i=0; i<nocs; i++) {
-               if ( colst[i]->co_oc->soc_required ) {
-                       AttributeType **at = colst[i]->co_oc->soc_required;
+               if ( (*colst[i]->co_oc)->soc_required ) {
+                       AttributeType **at = (*colst[i]->co_oc)->soc_required;
                        for (j=0; at[j]; j++) {
                                for (a=e->e_attrs, prev=&e->e_attrs; a;
                                        prev = &(*prev)->a_next, a=a->a_next) {
@@ -2687,8 +2678,8 @@ sort_attrs( Entry *e, CfOcInfo **colst, int nocs )
                                }
                        }
                }
-               if ( colst[i]->co_oc->soc_allowed ) {
-                       AttributeType **at = colst[i]->co_oc->soc_allowed;
+               if ( (*colst[i]->co_oc)->soc_allowed ) {
+                       AttributeType **at = (*colst[i]->co_oc)->soc_allowed;
                        for (j=0; at[j]; j++) {
                                for (a=e->e_attrs, prev=&e->e_attrs; a;
                                        prev = &(*prev)->a_next, a=a->a_next) {
@@ -2874,20 +2865,20 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
        return 0;
 }
 
-static CfOcInfo **
+static ConfigOCs **
 count_ocs( Attribute *oc_at, int *nocs )
 {
        int i, j, n;
-       CfOcInfo co, *coptr, **colst;
+       ConfigOCs co, *coptr, **colst;
 
        /* count the objectclasses */
        for ( i=0; oc_at->a_nvals[i].bv_val; i++ );
        n = i;
-       colst = (CfOcInfo **)ch_malloc( n * sizeof(CfOcInfo *));
+       colst = (ConfigOCs **)ch_malloc( n * sizeof(ConfigOCs *));
 
        for ( i=0, j=0; i<n; i++) {
                co.co_name = &oc_at->a_nvals[i];
-               coptr = avl_find( CfOcTree, &co, CfOcInfo_cmp );
+               coptr = avl_find( CfOcTree, &co, CfOc_cmp );
                
                /* ignore non-config objectclasses. probably should be
                 * an error, general data doesn't belong here.
@@ -2903,18 +2894,91 @@ count_ocs( Attribute *oc_at, int *nocs )
        return colst;
 }
 
+static int
+cfAddInclude( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
+{
+       if ( p->ce_type != Cft_Global && p->ce_type != Cft_Include )
+               return LDAP_CONSTRAINT_VIOLATION;
+
+       /* If we're reading from a configdir, don't parse this entry */
+       if ( ca->lineno )
+               return LDAP_COMPARE_TRUE;
+
+       if ( p->ce_type == Cft_Global )
+               cfn = &cf_prv;
+       else
+               cfn = p->ce_private;
+       ca->private = cfn;
+       return LDAP_SUCCESS;
+}
+
+static int
+cfAddSchema( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
+{
+       ConfigFile *cfo;
+
+       /* This entry is hardcoded, don't re-parse it */
+       if ( p->ce_type == Cft_Global ) {
+               cfn = &cf_prv;
+               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;
+       cfo = p->ce_private;
+       cfn->c_sibs = cfo->c_kids;
+       cfo->c_kids = cfn;
+       return LDAP_SUCCESS;
+}
+
+static int
+cfAddDatabase( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
+{
+       if ( p->ce_type != Cft_Global )
+               return LDAP_CONSTRAINT_VIOLATION;
+       ca->be = frontendDB;    /* just to get past check_vals */
+       return LDAP_SUCCESS;
+}
+
+static int
+cfAddBackend( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
+{
+       if ( p->ce_type != Cft_Global )
+               return LDAP_CONSTRAINT_VIOLATION;
+       return LDAP_SUCCESS;
+}
+
+static int
+cfAddModule( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
+{
+       if ( p->ce_type != Cft_Global )
+               return LDAP_CONSTRAINT_VIOLATION;
+       return LDAP_SUCCESS;
+}
+
+static int
+cfAddOverlay( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
+{
+       if ( p->ce_type != Cft_Database )
+               return LDAP_CONSTRAINT_VIOLATION;
+       ca->be = p->ce_be;
+       return LDAP_SUCCESS;
+}
+
 /* Parse an LDAP entry into config directives */
 static int
 config_add_internal( CfBackInfo *cfb, Entry *e, SlapReply *rs, int *renum )
 {
        CfEntryInfo *ce, *last;
-       CfOcInfo **colst;
-       Attribute *a, *oc_at, *type_attr;
-       AttributeDescription *type_ad = NULL;
+       ConfigOCs **colst;
+       Attribute *a, *oc_at;
        int i, j, nocs, rc = 0;
        ConfigArgs ca = {0};
        struct berval pdn;
-       ConfigTable *ct, *type_ct = NULL;
+       ConfigTable *ct;
        char *ptr;
 
        /* Make sure parent exists and entry does not */
@@ -2936,123 +3000,56 @@ config_add_internal( CfBackInfo *cfb, Entry *e, SlapReply *rs, int *renum )
        oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
        if ( !oc_at ) return LDAP_OBJECT_CLASS_VIOLATION;
 
-       colst = count_ocs( oc_at, &nocs );
-
-       /* Only the root can be Cft_Global, everything else must
-        * have a parent. Only limited nesting arrangements are allowed.
+       /* Fake the coordinates based on whether we're part of an
+        * LDAP Add or if reading the config dir
         */
-       switch( colst[0]->co_type ) {
-       case Cft_Global:
-               if ( last )  {
-                       rc = LDAP_CONSTRAINT_VIOLATION;
-                       goto leave;
-               }
-               break;
-       case Cft_Schema:
-       case Cft_Backend:
-       case Cft_Database:
-       case Cft_Include:
-               if ( !last || ( last->ce_type != Cft_Global &&
-                       last->ce_type != colst[0]->co_type )) {
-                       rc = LDAP_CONSTRAINT_VIOLATION;
-                       goto leave;
-               }
-               break;
-       case Cft_Overlay:
-               if ( !last || ( last->ce_type != Cft_Global &&
-                       last->ce_type != Cft_Database &&
-                       last->ce_type != colst[0]->co_type )) {
-                       rc = LDAP_CONSTRAINT_VIOLATION;
-                       goto leave;
-               }
-               break;
-#ifdef SLAPD_MODULES
-       case Cft_Module:
-               if ( !last || last->ce_type != Cft_Global ) {
-                       rc = LDAP_CONSTRAINT_VIOLATION;
-                       goto leave;
-               }
-#endif
-               break;
+       if ( rs ) {
+               ca.fname = "slapd";
+               ca.lineno = 0;
+       } else {
+               ca.fname = cfdir.bv_val;
+               ca.lineno = 1;
        }
 
-       sort_attrs( e, colst, nocs );
+       colst = count_ocs( oc_at, &nocs );
 
-       /* Parse all the values and check for simple syntax errors before
-        * performing any set actions.
+       /* Only the root can be Cft_Global, everything else must
+        * have a parent. Only limited nesting arrangements are allowed.
         */
-       switch (colst[0]->co_type) {
-       case Cft_Schema:
-               /* The cn=schema entry is all hardcoded, so never reparse it */
-               if (last->ce_type == Cft_Global )
-                       goto ok;
-               cfn = ch_calloc( 1, sizeof(ConfigFile) );
-               ca.private = cfn;
-               break;
-       case Cft_Global:
+       rc = LDAP_CONSTRAINT_VIOLATION;
+       if ( colst[0]->co_type == Cft_Global && !last ) {
                cfn = &cf_prv;
                ca.private = cfn;
                ca.be = frontendDB;     /* just to get past check_vals */
-               break;
+               rc = LDAP_SUCCESS;
+       }
 
-       case Cft_Backend:
-               if ( last->ce_type == Cft_Backend )
-                       ca.bi = last->ce_bi;
-               else
-                       type_ad = cfAd_backend;
-               break;
-       case Cft_Database:
-               if ( last->ce_type == Cft_Database ) {
-                       ca.be = last->ce_be;
-               } else {
-                       type_ad = cfAd_database;
-                       /* dummy, just to get past check_vals */
-                       ca.be = frontendDB;
+       /* Check whether the Add is allowed by its parent, and do
+        * any necessary arg setup
+        */
+       if ( last ) {
+               for ( i=0; i<nocs; i++ ) {
+                       if ( colst[i]->co_ldadd &&
+                               ( rc = colst[i]->co_ldadd( last, e, &ca ))
+                                       != LDAP_CONSTRAINT_VIOLATION ) {
+                               break;
+                       }
                }
-               break;
-
-       case Cft_Overlay:
-               ca.be = last->ce_be;
-               type_ad = cfAd_overlay;
-               break;
+       }
 
-       case Cft_Include:
-               if ( !rs ) {
-                       nocs = 0; /* ignored */
-                       break;
-               }
-               if ( last->ce_type == Cft_Global )
-                       cfn = &cf_prv;
-               else
-                       cfn = last->ce_private;
-               type_ad = cfAd_include;
-               break;
-#ifdef SLAPD_MODULES
-       case Cft_Module: {
-#if 0
-               ModPaths *mp;
-               char *ptr;
-               ptr = strchr( e->e_name.bv_val, '{' );
-               if ( !ptr ) {
-                       rc = LDAP_NAMING_VIOLATION;
-                       goto leave;
-               }
-               j = atoi(ptr+1);
-               for (i=0, mp=&modpaths; mp && i<j; mp=mp->mp_next);
-               /* There is no corresponding modpath for this load? */
-               if ( i != j ) {
-                       rc = LDAP_NAMING_VIOLATION;
-                       goto leave;
-               }
-               module_path( mp->mp_path.bv_val );
-               ca.private = mp;
-#endif
-               }
-               break;
-#endif
+       /* Add the entry but don't parse it, we already have its contents */
+       if ( rc == LDAP_COMPARE_TRUE ) {
+               rc = LDAP_SUCCESS;
+               goto ok;
        }
 
-       /* If doing an LDAPadd, check for indexed names and any necessary
+       if ( rc != LDAP_SUCCESS )
+               goto leave;
+
+       /* Parse all the values and check for simple syntax errors before
+        * performing any set actions.
+        *
+        * If doing an LDAPadd, check for indexed names and any necessary
         * renaming/renumbering. Entries that don't need indexed names are
         * ignored. Entries that need an indexed name and arrive without one
         * are assigned to the end. Entries that arrive with an index may
@@ -3070,22 +3067,12 @@ config_add_internal( CfBackInfo *cfb, Entry *e, SlapReply *rs, int *renum )
                goto leave;
 
        init_config_argv( &ca );
-       if ( type_ad ) {
-               type_attr = attr_find( e->e_attrs, type_ad );
-               if ( !type_attr ) {
-                       rc = LDAP_OBJECT_CLASS_VIOLATION;
-                       goto leave;
-               }
-               type_ct = config_find_table( colst, nocs, type_ad );
-               if ( !type_ct ) {
-                       rc = LDAP_OBJECT_CLASS_VIOLATION;
-                       goto leave;
-               }
-               rc = check_vals( type_ct, &ca, type_attr, 1);
-               if ( rc ) goto leave;
-       }
+
+       /* Make sure we process attrs in the required order */
+       sort_attrs( e, colst, nocs );
+
        for ( a=e->e_attrs; a; a=a->a_next ) {
-               if ( a == type_attr || a == oc_at ) continue;
+               if ( a == oc_at ) continue;
                ct = config_find_table( colst, nocs, a->a_desc );
                if ( !ct ) continue;    /* user data? */
                rc = check_vals( ct, &ca, a, 1 );
@@ -3093,21 +3080,8 @@ config_add_internal( CfBackInfo *cfb, Entry *e, SlapReply *rs, int *renum )
        }
 
        /* Basic syntax checks are OK. Do the actual settings. */
-       if ( type_ct ) {
-               ca.line = type_attr->a_vals[0].bv_val;
-               if ( type_ad->ad_type->sat_flags & SLAP_AT_ORDERED ) {
-                       ptr = strchr( ca.line, '}' );
-                       if ( ptr ) ca.line = ptr+1;
-               }
-               ca.valx = 0;
-               rc = config_parse_add( type_ct, &ca );
-               if ( rc ) {
-                       rc = LDAP_OTHER;
-                       goto leave;
-               }
-       }
        for ( a=e->e_attrs; a; a=a->a_next ) {
-               if ( a == type_attr || a == oc_at ) continue;
+               if ( a == oc_at ) continue;
                ct = config_find_table( colst, nocs, a->a_desc );
                if ( !ct ) continue;    /* user data? */
                for (i=0; a->a_vals[i].bv_val; i++) {
@@ -3214,7 +3188,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
        Entry *e = ce->ce_entry;
        Attribute *save_attrs = e->e_attrs, *oc_at;
        ConfigTable *ct;
-       CfOcInfo **colst;
+       ConfigOCs **colst;
        int i, nocs;
        char *ptr;
        delrec *dels = NULL, *deltail = NULL;
@@ -3230,6 +3204,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
        ca->be = ce->ce_be;
        ca->bi = ce->ce_bi;
        ca->private = ce->ce_private;
+       ca->ca_entry = e;
        strcpy( ca->log, "back-config" );
 
        for (ml = op->orm_modlist; ml; ml=ml->sml_next) {
@@ -3597,121 +3572,119 @@ out:
        return 0;
 }
 
-static Entry *
-config_alloc_entry( CfEntryInfo *parent, struct berval *rdn )
+static void
+config_build_attrs( Entry *e, AttributeType **at, AttributeDescription *ad,
+       ConfigTable *ct, ConfigArgs *c )
+{
+       int i, rc;
+
+       for (; at && *at; at++) {
+               /* Skip the naming attr */
+               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) {
+                               rc = config_get_vals(&ct[i], c);
+                               if (rc == LDAP_SUCCESS) {
+                                       if ( c->rvalue_nvals )
+                                               attr_merge(e, ct[i].ad, c->rvalue_vals,
+                                                       c->rvalue_nvals);
+                                       else
+                                               attr_merge_normalize(e, ct[i].ad,
+                                                       c->rvalue_vals, NULL);
+                                       ber_bvarray_free( c->rvalue_nvals );
+                                       ber_bvarray_free( c->rvalue_vals );
+                               }
+                               break;
+                       }
+               }
+       }
+}
+
+Entry *
+config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
+       ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra )
 {
        Entry *e = ch_calloc( 1, sizeof(Entry) );
        CfEntryInfo *ce = ch_calloc( 1, sizeof(CfEntryInfo) );
+       struct berval val;
+       struct berval ad_name;
+       AttributeDescription *ad = NULL;
+       int rc;
+       char *ptr;
+       const char *text;
+       Attribute *oc_at;
        struct berval pdn;
+       ObjectClass *oc;
+       CfEntryInfo *ceprev = NULL;
 
        e->e_private = ce;
        ce->ce_entry = e;
        ce->ce_parent = parent;
        if ( parent ) {
                pdn = parent->ce_entry->e_nname;
+               if ( parent->ce_kids )
+                       for ( ceprev = parent->ce_kids; ceprev->ce_sibs;
+                               ceprev = ceprev->ce_sibs );
        } else {
                BER_BVZERO( &pdn );
        }
 
+       ce->ce_type = main->co_type;
+       ce->ce_private = c->private;
+       ce->ce_be = c->be;
+       ce->ce_bi = c->bi;
+
        build_new_dn( &e->e_name, &pdn, rdn, NULL );
        ber_dupbv( &e->e_nname, &e->e_name );
-       return e;
-}
-
-#define        NO_TABLE        0
-#define        BI_TABLE        1
-#define        BE_TABLE        2
-
-static int
-config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc,
-        struct berval *rdn, ConfigTable *ct, int table )
-{
-       struct berval val;
-       struct berval ad_name;
-       AttributeDescription *ad = NULL;
-       int rc, i;
-       char *ptr;
-       const char *text;
-       AttributeType **at;
-       Attribute *oc_at;
 
-       val = oc->soc_cname;
-       attr_merge_normalize_one(e, slap_schema.si_ad_objectClass, &val, NULL );
+       attr_merge_normalize_one(e, slap_schema.si_ad_objectClass,
+               main->co_name, NULL );
+       if ( extra )
+               attr_merge_normalize_one(e, slap_schema.si_ad_objectClass,
+                       extra->co_name, NULL );
        ptr = strchr(rdn->bv_val, '=');
        ad_name.bv_val = rdn->bv_val;
        ad_name.bv_len = ptr - rdn->bv_val;
        rc = slap_bv2ad( &ad_name, &ad, &text );
        if ( rc ) {
-               return rc;
+               return NULL;
        }
        val.bv_val = ptr+1;
        val.bv_len = rdn->bv_len - (val.bv_val - rdn->bv_val);
        attr_merge_normalize_one(e, ad, &val, NULL );
 
-       for (at=oc->soc_required; at && *at; at++) {
-               /* Skip the naming attr */
-               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) {
-                               rc = config_get_vals(&ct[i], c);
-                               if (rc == LDAP_SUCCESS) {
-                                       if ( c->rvalue_nvals )
-                                               attr_merge(e, ct[i].ad, c->rvalue_vals,
-                                                       c->rvalue_nvals);
-                                       else
-                                               attr_merge_normalize(e, ct[i].ad,
-                                                       c->rvalue_vals, NULL);
-                                       ber_bvarray_free( c->rvalue_nvals );
-                                       ber_bvarray_free( c->rvalue_vals );
-                               }
-                               break;
-                       }
-               }
-       }
+       oc = *main->co_oc;
+       if ( oc->soc_required )
+               config_build_attrs( e, oc->soc_required, ad, main->co_table, c );
 
-       for (at=oc->soc_allowed; at && *at; at++) {
-               /* Skip the naming attr */
-               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) {
-                               rc = config_get_vals(&ct[i], c);
-                               if (rc == LDAP_SUCCESS) {
-                                       if ( c->rvalue_nvals )
-                                               attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
-                                       else
-                                               attr_merge_normalize(e, ct[i].ad, c->rvalue_vals, NULL);
-                                       ber_bvarray_free( c->rvalue_nvals );
-                                       ber_bvarray_free( c->rvalue_vals );
-                               }
-                               break;
-                       }
-               }
-       }
+       if ( oc->soc_allowed )
+               config_build_attrs( e, oc->soc_allowed, ad, main->co_table, c );
 
-       if ( table ) {
-               if ( table == BI_TABLE )
-                       ct = c->bi->bi_cf_table;
-               else
-                       ct = c->be->be_cf_table;
-               for (;ct && ct->name;ct++) {
-                       if (!ct->ad) continue;
-                       rc = config_get_vals(ct, c);
-                       if (rc == LDAP_SUCCESS) {
-                               if ( c->rvalue_nvals )
-                                       attr_merge(e, ct->ad, c->rvalue_vals, c->rvalue_nvals);
-                               else
-                                       attr_merge_normalize(e, ct->ad, c->rvalue_vals, NULL);
-                       }
-               }
+       if ( extra ) {
+               oc = *extra->co_oc;
+               if ( oc->soc_required )
+                       config_build_attrs( e, oc->soc_required, ad, main->co_table, c );
+
+               if ( oc->soc_allowed )
+                       config_build_attrs( e, oc->soc_allowed, ad, main->co_table, c );
        }
+
        oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
        rc = structural_class(oc_at->a_vals, &val, NULL, &text, c->msg,
                sizeof(c->msg));
        attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &val, NULL );
+       if ( op ) {
+               op->ora_e = e;
+               op->o_bd->be_add( op, rs );
+       }
+       if ( ceprev ) {
+               ceprev->ce_sibs = ce;
+       } else if ( parent ) {
+               parent->ce_kids = ce;
+       }
 
-       return 0;
+       return e;
 }
 
 static void
@@ -3720,15 +3693,9 @@ config_build_schema_inc( ConfigArgs *c, CfEntryInfo *ceparent,
 {
        Entry *e;
        ConfigFile *cf = c->private;
-       CfEntryInfo *ce, *ceprev;
        char *ptr;
        struct berval bv;
 
-       if ( ceparent->ce_kids ) {
-               for ( ceprev = ceparent->ce_kids; ceprev->ce_sibs;
-                       ceprev = ceprev->ce_sibs );
-       }
-
        for (; cf; cf=cf->c_sibs, c->depth++) {
                c->value_dn.bv_val = c->log;
                bv.bv_val = strrchr(cf->c_file.bv_val, LDAP_DIRSEP[0]);
@@ -3747,115 +3714,55 @@ 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';
 
-               e = config_alloc_entry( ceparent, &c->value_dn );
                c->private = cf;
-               config_build_entry( c, e, cfOc_schema, &c->value_dn,
-                       c->bi->bi_cf_table, NO_TABLE );
-               ce = e->e_private;
-               ce->ce_private = cf;
-               ce->ce_type = Cft_Schema;
-               if ( op ) {
-                       op->ora_e = e;
-                       op->o_bd->be_add( op, rs );
-               }
-               ce->ce_bi = c->bi;
-               if ( !ceparent->ce_kids ) {
-                       ceparent->ce_kids = ce;
-               } else {
-                       ceprev->ce_sibs = ce;
-               }
-               ceprev = ce;
-               if ( cf->c_kids ) {
+               e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
+                       &CFOC_SCHEMA, NULL );
+               if ( e && cf->c_kids ) {
                        c->private = cf->c_kids;
-                       config_build_schema_inc( c, ceparent, op, rs );
+                       config_build_schema_inc( c, e->e_private, op, rs );
                }
        }
 }
 
-static CfEntryInfo *
+static void
 config_build_includes( ConfigArgs *c, CfEntryInfo *ceparent,
        Operation *op, SlapReply *rs )
 {
        Entry *e;
        int i;
        ConfigFile *cf = c->private;
-       CfEntryInfo *ce, *ceprev;
-
-       if ( ceparent->ce_kids ) {
-               for ( ceprev = ceparent->ce_kids; ceprev->ce_sibs;
-                       ceprev = ceprev->ce_sibs );
-       }
 
        for (i=0; cf; cf=cf->c_sibs, i++) {
                c->value_dn.bv_val = c->log;
                c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=include" IFMT, i);
-               e = config_alloc_entry( ceparent, &c->value_dn );
                c->private = cf;
-               config_build_entry( c, e, cfOc_include, &c->value_dn,
-                       c->bi->bi_cf_table, NO_TABLE );
-               if ( op ) {
-                       op->ora_e = e;
-                       op->o_bd->be_add( op, rs );
-               }
-               ce = e->e_private;
-               ce->ce_private = cf;
-               ce->ce_type = Cft_Include;
-               ce->ce_bi = c->bi;
-               if ( !ceparent->ce_kids ) {
-                       ceparent->ce_kids = ce;
-               } else {
-                       ceprev->ce_sibs = ce;
-               }
-               ceprev = ce;
-               if ( cf->c_kids ) {
+               e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
+                       &CFOC_INCLUDE, NULL );
+               if ( e && cf->c_kids ) {
                        c->private = cf->c_kids;
-                       config_build_includes( c, ce, op, rs );
+                       config_build_includes( c, e->e_private, op, rs );
                }
        }
-       return ce;
 }
 
 #ifdef SLAPD_MODULES
 
-static CfEntryInfo *
+static void
 config_build_modules( ConfigArgs *c, CfEntryInfo *ceparent,
        Operation *op, SlapReply *rs )
 {
-       Entry *e;
        int i;
-       CfEntryInfo *ce, *ceprev;
        ModPaths *mp;
 
-       if ( ceparent->ce_kids ) {
-               for ( ceprev = ceparent->ce_kids; ceprev->ce_sibs;
-                       ceprev = ceprev->ce_sibs );
-       }
-
        for (i=0, mp=&modpaths; mp; mp=mp->mp_next, i++) {
                if ( BER_BVISNULL( &mp->mp_path ) && !mp->mp_loads )
                        continue;
                c->value_dn.bv_val = c->log;
                c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=module" IFMT, i);
-               e = config_alloc_entry( ceparent, &c->value_dn );
-               ce = e->e_private;
-               ce->ce_type = Cft_Include;
                c->private = mp;
-               ce->ce_private = mp;
-               config_build_entry( c, e, cfOc_module, &c->value_dn,
-                       c->bi->bi_cf_table, NO_TABLE );
-               if ( op ) {
-                       op->ora_e = e;
-                       op->o_bd->be_add( op, rs );
-               }
-               ce->ce_bi = c->bi;
-               if ( !ceparent->ce_kids ) {
-                       ceparent->ce_kids = ce;
-               } else {
-                       ceprev->ce_sibs = ce;
-               }
-               ceprev = ce;
+               config_build_entry( op, rs, ceparent, c, &c->value_dn,
+                       &CFOC_MODULE, NULL );
        }
-       return ce;
 }
 #endif
 
@@ -3897,21 +3804,10 @@ config_back_db_open( BackendDB *be )
 
        /* create root of tree */
        rdn = config_rdn;
-       e = config_alloc_entry( NULL, &rdn );
+       c.private = cfb->cb_config;
+       e = config_build_entry( op, &rs, NULL, &c, &rdn, &CFOC_GLOBAL, NULL );
        ce = e->e_private;
-       ce->ce_type = Cft_Global;
        cfb->cb_root = ce;
-       c.be = be;
-       c.bi = be->bd_info;
-       c.private = cfb->cb_config;
-       ct = c.bi->bi_cf_table;
-       ce->ce_private = c.private;
-       config_build_entry( &c, e, cfOc_global, &rdn, ct, NO_TABLE );
-       if ( op ) {
-               op->ora_e = e;
-               op->o_bd->be_add( op, &rs );
-       }
-       ce->ce_bi = c.bi;
 
        parent = e;
        ceparent = ce;
@@ -3921,21 +3817,8 @@ config_back_db_open( BackendDB *be )
         * files.
         */
        rdn = schema_rdn;
-       e = config_alloc_entry( ceparent, &rdn );
-       ce = e->e_private;
-       ce->ce_type = Cft_Schema;
        c.private = NULL;
-       config_build_entry( &c, e, cfOc_schema, &rdn, ct, NO_TABLE );
-       if ( op ) {
-               op->ora_e = e;
-               op->o_bd->be_add( op, &rs );
-       }
-       if ( !ceparent->ce_kids ) {
-               ceparent->ce_kids = ce;
-       } else {
-               ceprev->ce_sibs = ce;
-       }
-       ceprev = ce;
+       e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_SCHEMA, NULL );
 
        /* Create includeFile nodes and schema nodes for included schema... */
        if ( cfb->cb_config->c_kids ) {
@@ -3943,13 +3826,13 @@ config_back_db_open( BackendDB *be )
                c.private = cfb->cb_config->c_kids;
                config_build_schema_inc( &c, ce, op, &rs );
                c.private = cfb->cb_config->c_kids;
-               ceprev = config_build_includes( &c, ceparent, op, &rs );
+               config_build_includes( &c, ceparent, op, &rs );
        }
 
 #ifdef SLAPD_MODULES
        /* Create Module nodes... */
        if ( modpaths.mp_loads ) {
-               ceprev = config_build_modules( &c, ceparent, op, &rs );
+               config_build_modules( &c, ceparent, op, &rs );
        }
 #endif
 
@@ -3959,27 +3842,14 @@ config_back_db_open( BackendDB *be )
        
        c.line = 0;
        LDAP_STAILQ_FOREACH( bi, &backendInfo, bi_next) {
-               if (!bi->bi_cf_table) continue;
+               if (!bi->bi_cf_ocs) continue;
                if (!bi->bi_private) continue;
 
                rdn.bv_val = c.log;
                rdn.bv_len = sprintf(rdn.bv_val, "%s=%s", cfAd_backend->ad_cname.bv_val, bi->bi_type);
-               e = config_alloc_entry( ceparent, &rdn );
-               ce = e->e_private;
-               ce->ce_type = Cft_Backend;
-               ce->ce_bi = bi;
                c.bi = bi;
-               config_build_entry( &c, e, cfOc_backend, &rdn, ct, BI_TABLE );
-               if ( op ) {
-                       op->ora_e = e;
-                       op->o_bd->be_add( op, &rs );
-               }
-               if ( !ceparent->ce_kids ) {
-                       ceparent->ce_kids = ce;
-               } else {
-                       ceprev->ce_sibs = ce;
-               }
-               ceprev = ce;
+               e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_BACKEND,
+                       bi->bi_cf_ocs );
        }
 
        /* Create database nodes... */
@@ -4001,53 +3871,25 @@ config_back_db_open( BackendDB *be )
                rdn.bv_val = c.log;
                rdn.bv_len = sprintf(rdn.bv_val, "%s=" IFMT "%s", cfAd_database->ad_cname.bv_val,
                        i, bi->bi_type);
-               e = config_alloc_entry( ceparent, &rdn );
-               ce = e->e_private;
                c.be = bptr;
                c.bi = bi;
-               ce->ce_type = Cft_Database;
-               ce->ce_be = c.be;
-               ce->ce_bi = c.bi;
-               config_build_entry( &c, e, cfOc_database, &rdn, ct, BE_TABLE );
-               if ( op ) {
-                       op->ora_e = e;
-                       op->o_bd->be_add( op, &rs );
-               }
-               if ( !ceparent->ce_kids ) {
-                       ceparent->ce_kids = ce;
-               } else {
-                       ceprev->ce_sibs = ce;
-               }
-               ceprev = ce;
+               e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_DATABASE,
+                       be->be_cf_ocs );
+               ce = e->e_private;
                /* Iterate through overlays */
                if ( oi ) {
                        slap_overinst *on;
                        Entry *oe;
-                       CfEntryInfo *opar = ce, *oprev = NULL;
                        int j;
 
                        for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
                                rdn.bv_val = c.log;
                                rdn.bv_len = sprintf(rdn.bv_val, "%s=" IFMT "%s",
                                        cfAd_overlay->ad_cname.bv_val, j, on->on_bi.bi_type );
-                               oe = config_alloc_entry( opar, &rdn );
-                               ce = oe->e_private;
                                c.be = bptr;
                                c.bi = &on->on_bi;
-                               ce->ce_type = Cft_Overlay;
-                               ce->ce_be = c.be;
-                               ce->ce_bi = c.bi;
-                               config_build_entry( &c, oe, cfOc_overlay, &rdn, ct, BI_TABLE );
-                               if ( op ) {
-                                       op->ora_e = oe;
-                                       op->o_bd->be_add( op, &rs );
-                               }
-                               if ( !opar->ce_kids ) {
-                                       opar->ce_kids = ce;
-                               } else {
-                                       oprev->ce_sibs = ce;
-                               }
-                               oprev = ce;
+                               oe = config_build_entry( op, &rs, ce, &c, &rdn,
+                                       &CFOC_OVERLAY, c.bi->bi_cf_ocs );
                        }
                }
        }
@@ -4261,7 +4103,7 @@ config_back_initialize( BackendInfo *bi )
                parse_oidm( "slapd", i, 3, argv, 0, NULL );
        }
 
-       bi->bi_cf_table = ct;
+       bi->bi_cf_ocs = cf_ocs;
 
        i = config_register_schema( ct, cf_ocs );
        if ( i ) return i;
index 0af0616762109d930c4f1b7d5ad1314606fabb66..fc42f496612ac0a3ff4484a9369686e3cd27a586 100644 (file)
@@ -78,7 +78,8 @@ static int fp_parse_line(ConfigArgs *c);
 
 static char    *strtok_quote(char *line, char *sep, char **quote_ptr);
 
-int read_config_file(const char *fname, int depth, ConfigArgs *cf);
+int read_config_file(const char *fname, int depth, ConfigArgs *cf,
+       ConfigTable *cft );
 
 ConfigArgs *
 new_config_args( BackendDB *be, const char *fname, int lineno, int argc, char **argv )
@@ -445,26 +446,26 @@ int
 init_config_ocs( ConfigOCs *ocs ) {
        int i;
 
-       for (i=0;ocs[i].def;i++) {
+       for (i=0;ocs[i].co_def;i++) {
                LDAPObjectClass *oc;
                int code;
                const char *err;
 
-               oc = ldap_str2objectclass( ocs[i].def, &code, &err,
+               oc = ldap_str2objectclass( ocs[i].co_def, &code, &err,
                        LDAP_SCHEMA_ALLOW_ALL );
                if ( !oc ) {
                        fprintf( stderr, "init_config_ocs: objectclass \"%s\": %s, %s\n",
-                               ocs[i].def, ldap_scherr2str(code), err );
+                               ocs[i].co_def, ldap_scherr2str(code), err );
                        return code;
                }
                code = oc_add(oc,0,NULL,&err);
                if ( code && code != SLAP_SCHERR_CLASS_DUP ) {
                        fprintf( stderr, "init_config_ocs: objectclass \"%s\": %s, %s\n",
-                               ocs[i].def, scherr2str(code), err );
+                               ocs[i].co_def, scherr2str(code), err );
                        return code;
                }
-               if ( ocs[i].oc ) {
-                       *ocs[i].oc = oc_find(oc->oc_names[0]);
+               if ( ocs[i].co_oc ) {
+                       *ocs[i].co_oc = oc_find(oc->oc_names[0]);
                }
                ldap_memfree(oc);
        }
@@ -513,7 +514,7 @@ config_parse_add(ConfigTable *ct, ConfigArgs *c)
 }
 
 int
-read_config_file(const char *fname, int depth, ConfigArgs *cf)
+read_config_file(const char *fname, int depth, ConfigArgs *cf, ConfigTable *cft)
 {
        FILE *fp;
        ConfigTable *ct;
@@ -582,7 +583,7 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf)
 
                c->op = SLAP_CONFIG_ADD;
 
-               ct = config_find_keyword( config_back_cf_table, c );
+               ct = config_find_keyword( cft, c );
                if ( ct ) {
                        rc = config_add_vals( ct, c );
                        if ( !rc ) continue;
@@ -601,8 +602,8 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf)
                        
                } 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 ( c->bi->bi_cf_ocs->co_table ) {
+                               ct = config_find_keyword( c->bi->bi_cf_ocs->co_table, c );
                                if ( ct ) {
                                        rc = config_add_vals( ct, c );
                                }
@@ -629,8 +630,8 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf)
 
                } else if ( c->be ) {
                        rc = SLAP_CONF_UNKNOWN;
-                       if ( c->be->be_cf_table ) {
-                               ct = config_find_keyword( c->be->be_cf_table, c );
+                       if ( c->be->be_cf_ocs ) {
+                               ct = config_find_keyword( c->be->be_cf_ocs->co_table, c );
                                if ( ct ) {
                                        rc = config_add_vals( ct, c );
                                }
@@ -1155,7 +1156,7 @@ int config_generic_wrapper( Backend *be, const char *fname, int lineno,
        sprintf( c.log, "%s: line %lu", fname, lineno );
 
        rc = SLAP_CONF_UNKNOWN;
-       ct = config_find_keyword( be->be_cf_table, &c );
+       ct = config_find_keyword( be->be_cf_ocs->co_table, &c );
        if ( ct )
                rc = config_add_vals( ct, &c );
        return rc;
index 909314c60ef0149b9535a36a7d45e6f0557ef081..bc06027e1a44fce80d6d0c9ffdcd93e727f012ab 100644 (file)
@@ -35,7 +35,8 @@ typedef enum {
        Cft_Database,
        Cft_Overlay,
        Cft_Include,
-       Cft_Module
+       Cft_Module,
+       Cft_Misc        /* backend/overlay defined */
 } ConfigType;
 
 #define ARGS_USERLAND  0x00000fff
@@ -66,16 +67,38 @@ typedef enum {
 
 #define ARG_BAD_CONF   0xdead0000      /* overload return values */
 
-extern ConfigTable config_back_cf_table[];
+/* This is a config entry's e_private data */
+typedef struct CfEntryInfo {
+       struct CfEntryInfo *ce_parent;
+       struct CfEntryInfo *ce_sibs;
+       struct CfEntryInfo *ce_kids;
+       Entry *ce_entry;
+       ConfigType ce_type;
+       BackendInfo *ce_bi;
+       BackendDB *ce_be;
+       void *ce_private;
+} CfEntryInfo;
+
+struct config_args_s;
+
+/* Check if the child is allowed to be LDAPAdd'd to the parent */
+typedef int (ConfigLDAPadd)(
+       CfEntryInfo *parent, Entry *child, struct config_args_s *ca);
+
+/* Let the object create children out of slapd.conf */
+typedef int (ConfigCfAdd)(
+       Operation *op, SlapReply *rs, Entry *parent, struct config_args_s *ca );
 
 typedef struct ConfigOCs {
-       char *def;
-       ConfigType cft;
-       ObjectClass **oc;
+       char *co_def;
+       ConfigType co_type;
+       ObjectClass **co_oc;
+       ConfigTable *co_table;
+       ConfigLDAPadd *co_ldadd;
+       ConfigCfAdd *co_cfadd;
+       struct berval *co_name;
 } ConfigOCs;
 
-struct config_args_s;
-
 typedef int (ConfigDriver)(struct config_args_s *c);
 
 typedef struct config_args_s {
@@ -111,6 +134,7 @@ typedef struct config_args_s {
        int type;       /* ConfigTable.arg_type & ARGS_USERLAND */
        BackendDB *be;
        BackendInfo *bi;
+       Entry *ca_entry;        /* entry being modified */
        void *private;  /* anything */
        ConfigDriver *cleanup;
 } ConfigArgs;
@@ -127,3 +151,5 @@ int config_register_schema(ConfigTable *ct, ConfigOCs *co);
 int config_get_vals(ConfigTable *ct, ConfigArgs *c);
 int config_add_vals(ConfigTable *ct, ConfigArgs *c);
 ConfigTable * config_find_keyword(ConfigTable *ct, ConfigArgs *c);
+Entry * config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
+       ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra );
index ec075734e73b22f3cde84810175b94732ed54755..c8ffe0ba33ff29938f6cb46ce0e813a972a04328 100644 (file)
@@ -1605,6 +1605,8 @@ LDAP_TAILQ_HEAD( be_pcl, slap_csn_entry );
 #define        SLAP_MAX_CIDS   32      /* Maximum number of supported controls */
 #endif
 
+struct ConfigOCs;      /* config.h */
+
 struct slap_backend_db {
        BackendInfo     *bd_info;       /* pointer to shared backend info */
 
@@ -1775,7 +1777,7 @@ struct slap_backend_db {
        struct syncinfo_s                                               *be_syncinfo; /* For syncrepl */
 
        void    *be_pb;         /* Netscape plugin */
-       struct ConfigTable *be_cf_table;
+       struct ConfigOCs *be_cf_ocs;
 
        void    *be_private;    /* anything the backend database needs     */
        LDAP_STAILQ_ENTRY(slap_backend_db) be_next;
@@ -1989,8 +1991,6 @@ typedef int (BI_tool_id2entry_get) LDAP_P(( BackendDB *be, ID id, Entry **e ));
 typedef ID (BI_tool_entry_modify) LDAP_P(( BackendDB *be, Entry *e, 
        struct berval *text ));
 
-struct ConfigTable;    /* config.h */
-
 struct slap_backend_info {
        char    *bi_type; /* type of backend */
 
@@ -2118,7 +2118,7 @@ struct slap_backend_info {
        char    bi_ctrls[SLAP_MAX_CIDS + 1];
 
        unsigned int bi_nDB;    /* number of databases of this type */
-       struct ConfigTable *bi_cf_table;
+       struct ConfigOCs *bi_cf_ocs;
        void    *bi_private;    /* anything the backend type needs */
        LDAP_STAILQ_ENTRY(slap_backend_info) bi_next ;
 };