]> git.sur5r.net Git - openldap/commitdiff
Better tracking of system schema, refresh cn=schema after moduleloads
authorHoward Chu <hyc@openldap.org>
Fri, 17 Nov 2006 22:52:20 +0000 (22:52 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 17 Nov 2006 22:52:20 +0000 (22:52 +0000)
servers/slapd/at.c
servers/slapd/bconfig.c
servers/slapd/oc.c
servers/slapd/oidm.c

index e02acf90a026cf63d6fb2bb3252f32e0ac4c2023..acdeff290bc7b28662e91ecc7738efadd25e1b9b 100644 (file)
@@ -62,7 +62,7 @@ static LDAP_STAILQ_HEAD(ATList, slap_attribute_type) attr_list
        = LDAP_STAILQ_HEAD_INITIALIZER(attr_list);
 
 /* Last hardcoded attribute registered */
-static AttributeType *attr_sys_tail;
+AttributeType *at_sys_tail;
 
 int at_oc_cache;
 
@@ -529,8 +529,8 @@ at_insert(
        }
 
        if ( sat->sat_flags & SLAP_AT_HARDCODE ) {
-               prev = attr_sys_tail;
-               attr_sys_tail = sat;
+               prev = at_sys_tail;
+               at_sys_tail = sat;
        }
        if ( prev ) {
                LDAP_STAILQ_INSERT_AFTER( &attr_list, prev, sat, sat_next );
@@ -924,7 +924,7 @@ at_unparse( BerVarray *res, AttributeType *start, AttributeType *end, int sys )
        /* count the result size */
        i = 0;
        for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) {
-               if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) continue;
+               if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break;
                i++;
                if ( at == end ) break;
        }
@@ -941,7 +941,7 @@ at_unparse( BerVarray *res, AttributeType *start, AttributeType *end, int sys )
        i = 0;
        for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) {
                LDAPAttributeType lat, *latp;
-               if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) continue;
+               if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break;
                if ( at->sat_oidmacro ) {
                        lat = at->sat_atype;
                        lat.at_oid = at->sat_oidmacro;
index 89b59891ab88ba2c61a24b89090c453c2e23f2c2..e8fa653bfdb082dedd97908d362582dc1d8c4e89 100644 (file)
 
 #include "config.h"
 
-static struct berval config_rdn = BER_BVC("cn=config");
-static struct berval schema_rdn = BER_BVC("cn=schema");
+#define        CONFIG_RDN      "cn=config"
+#define        SCHEMA_RDN      "cn=schema"
+
+static struct berval config_rdn = BER_BVC(CONFIG_RDN);
+static struct berval schema_rdn = BER_BVC(SCHEMA_RDN);
 
 extern int slap_DN_strict;     /* dn.c */
 
@@ -71,6 +74,8 @@ typedef struct {
        int             cb_use_ldif;
 } CfBackInfo;
 
+static CfBackInfo cfBackInfo;
+
 static char    *passwd_salt;
 static char    *logfileName;
 #ifdef SLAP_AUTH_REWRITE
@@ -81,15 +86,25 @@ static struct berval cfdir;
 
 /* Private state */
 static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
-       *cfAd_include;
+       *cfAd_include, *cfAd_attr, *cfAd_oc, *cfAd_om;
 
 static ConfigFile *cfn;
 
 static Avlnode *CfOcTree;
 
+/* System schema state */
+extern AttributeType *at_sys_tail;     /* at.c */
+extern ObjectClass *oc_sys_tail;       /* oc.c */
+extern OidMacro *om_sys_tail;  /* oidm.c */
+static AttributeType *cf_at_tail;
+static ObjectClass *cf_oc_tail;
+static OidMacro *cf_om_tail;
+
 static int config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca,
        SlapReply *rs, int *renumber, Operation *op );
 
+static int config_check_schema( CfBackInfo *cfb );
+
 static ConfigDriver config_fname;
 static ConfigDriver config_cfdir;
 static ConfigDriver config_generic;
@@ -1611,6 +1626,10 @@ config_generic(ConfigArgs *c) {
                                ber_str2bv(ptr, 0, 1, &bv);
                                ber_bvarray_add( &modcur->mp_loads, &bv );
                        }
+                       /* Check for any new hardcoded schema */
+                       if ( c->op == LDAP_MOD_ADD && CONFIG_ONLINE_ADD( c )) {
+                               config_check_schema( &cfBackInfo );
+                       }
                        break;
 
                case CFG_MODPATH:
@@ -4746,6 +4765,87 @@ config_build_modules( ConfigArgs *c, CfEntryInfo *ceparent,
 }
 #endif
 
+static int
+config_check_schema(CfBackInfo *cfb)
+{
+       struct berval schema_dn = BER_BVC(SCHEMA_RDN "," CONFIG_RDN);
+       ConfigArgs c = {0};
+       ConfigFile *cf = cfb->cb_config;
+       CfEntryInfo *ce, *last;
+       Entry *e;
+
+       /* If there's no root entry, we must be in the midst of converting */
+       if ( !cfb->cb_root )
+               return 0;
+
+       /* Make sure the main schema entry exists */
+       ce = config_find_base( cfb->cb_root, &schema_dn, &last );
+       if ( ce ) {
+               Attribute *a;
+               struct berval *bv;
+
+               e = ce->ce_entry;
+
+               /* Make sure it's up to date */
+               if ( cf_om_tail != om_sys_tail ) {
+                       a = attr_find( e->e_attrs, cfAd_om );
+                       if ( a ) {
+                               if ( a->a_nvals != a->a_vals )
+                                       ber_bvarray_free( a->a_nvals );
+                               ber_bvarray_free( a->a_vals );
+                               a->a_vals = NULL;
+                               a->a_nvals = NULL;
+                       }
+                       oidm_unparse( &bv, NULL, NULL, 1 );
+                       attr_merge_normalize( e, cfAd_om, bv, NULL );
+                       ber_bvarray_free( bv );
+                       cf_om_tail = om_sys_tail;
+               }
+               if ( cf_at_tail != at_sys_tail ) {
+                       a = attr_find( e->e_attrs, cfAd_attr );
+                       if ( a ) {
+                               if ( a->a_nvals != a->a_vals )
+                                       ber_bvarray_free( a->a_nvals );
+                               ber_bvarray_free( a->a_vals );
+                               a->a_vals = NULL;
+                               a->a_nvals = NULL;
+                       }
+                       at_unparse( &bv, NULL, NULL, 1 );
+                       attr_merge_normalize( e, cfAd_attr, bv, NULL );
+                       ber_bvarray_free( bv );
+                       cf_at_tail = at_sys_tail;
+               }
+               if ( cf_oc_tail != oc_sys_tail ) {
+                       a = attr_find( e->e_attrs, cfAd_oc );
+                       if ( a ) {
+                               if ( a->a_nvals != a->a_vals )
+                                       ber_bvarray_free( a->a_nvals );
+                               ber_bvarray_free( a->a_vals );
+                               a->a_vals = NULL;
+                               a->a_nvals = NULL;
+                       }
+                       oc_unparse( &bv, NULL, NULL, 1 );
+                       attr_merge_normalize( e, cfAd_oc, bv, NULL );
+                       ber_bvarray_free( bv );
+                       cf_oc_tail = oc_sys_tail;
+               }
+       } else {
+               SlapReply rs = {REP_RESULT};
+               c.private = NULL;
+               e = config_build_entry( NULL, &rs, cfb->cb_root, &c, &schema_rdn,
+                       &CFOC_SCHEMA, NULL );
+               if ( !e ) {
+                       return -1;
+               }
+               ce = e->e_private;
+               ce->ce_private = cfb->cb_config;
+               cf_at_tail = at_sys_tail;
+               cf_oc_tail = oc_sys_tail;
+               cf_om_tail = om_sys_tail;
+       }
+       return 0;
+}
+
 static const char *defacl[] = {
        NULL, "to", "*", "by", "*", "none", NULL
 };
@@ -4776,9 +4876,10 @@ config_back_db_open( BackendDB *be )
                parse_acl(be, "config_back_db_open", 0, 6, (char **)defacl, 0 );
        }
 
-       /* If we read the config from back-ldif, nothing to do here */
-       if ( cfb->cb_got_ldif )
-               return 0;
+       /* If we read the config from back-ldif, do some quick sanity checks */
+       if ( cfb->cb_got_ldif ) {
+               return config_check_schema( cfb );
+       }
 
        if ( cfb->cb_use_ldif ) {
                thrctx = ldap_pvt_thread_pool_context();
@@ -4838,6 +4939,9 @@ config_back_db_open( BackendDB *be )
        }
        ce = e->e_private;
        ce->ce_private = cfb->cb_config;
+       cf_at_tail = at_sys_tail;
+       cf_oc_tail = oc_sys_tail;
+       cf_om_tail = om_sys_tail;
 
        /* Create schema nodes for included schema... */
        if ( cfb->cb_config->c_kids ) {
@@ -5028,8 +5132,6 @@ config_back_db_destroy( BackendDB *be )
                backend_destroy_one( &cfb->cb_db, 0 );
        }
 
-       free( be->be_private );
-
        loglevel_destroy();
 
        return 0;
@@ -5041,7 +5143,7 @@ config_back_db_init( BackendDB *be )
        struct berval dn;
        CfBackInfo *cfb;
 
-       cfb = ch_calloc( 1, sizeof(CfBackInfo));
+       cfb = &cfBackInfo;
        cfb->cb_config = ch_calloc( 1, sizeof(ConfigFile));
        cfn = cfb->cb_config;
        be->be_private = cfb;
@@ -5145,9 +5247,12 @@ static struct {
        char *name;
        AttributeDescription **desc;
 } ads[] = {
+       { "attribute", &cfAd_attr },
        { "backend", &cfAd_backend },
        { "database", &cfAd_database },
        { "include", &cfAd_include },
+       { "objectclass", &cfAd_oc },
+       { "objectidentifier", &cfAd_om },
        { "overlay", &cfAd_overlay },
        { NULL, NULL }
 };
index 87ced2d7cb073183b6791a7254db9eb2187b9b39..c6b50fde48d25e702533a9edcff09f7e67186457 100644 (file)
@@ -134,7 +134,8 @@ static Avlnode      *oc_index = NULL;
 static Avlnode *oc_cache = NULL;
 static LDAP_STAILQ_HEAD(OCList, slap_object_class) oc_list
        = LDAP_STAILQ_HEAD_INITIALIZER(oc_list);
-static ObjectClass *oc_sys_tail;
+
+ObjectClass *oc_sys_tail;
 
 static int
 oc_index_cmp(
@@ -805,7 +806,7 @@ oc_unparse( BerVarray *res, ObjectClass *start, ObjectClass *end, int sys )
        /* count the result size */
        i = 0;
        for ( oc=start; oc; oc=LDAP_STAILQ_NEXT(oc, soc_next)) {
-               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) continue;
+               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) break;
                i++;
                if ( oc == end ) break;
        }
@@ -822,7 +823,7 @@ oc_unparse( BerVarray *res, ObjectClass *start, ObjectClass *end, int sys )
        i = 0;
        for ( oc=start; oc; oc=LDAP_STAILQ_NEXT(oc, soc_next)) {
                LDAPObjectClass loc, *locp;
-               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) continue;
+               if ( sys && !(oc->soc_flags & SLAP_OC_HARDCODE)) break;
                if ( oc->soc_oidmacro ) {
                        loc = oc->soc_oclass;
                        loc.oc_oid = oc->soc_oidmacro;
index 2fe6cc552c7f5db2ebd3e94dbbf2aa62abebcc40..3279336e8f819cac2a5f76fa6a59712776e8f00f 100644 (file)
@@ -29,7 +29,7 @@
 static LDAP_STAILQ_HEAD(OidMacroList, slap_oid_macro) om_list
        = LDAP_STAILQ_HEAD_INITIALIZER(om_list);
 
-static OidMacro *om_sys_tail;
+OidMacro *om_sys_tail;
 
 /* Replace an OID Macro invocation with its full numeric OID.
  * If the macro is used with "macroname:suffix" append ".suffix"
@@ -149,6 +149,7 @@ parse_oidm(
        if ( !user ) {
                om->som_flags |= SLAP_OM_HARDCODE;
                prev = om_sys_tail;
+               om_sys_tail = om;
        }
 
        if ( prev ) {
@@ -173,7 +174,7 @@ void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
        /* count the result size */
        i = 0;
        for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
-               if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) continue;
+               if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
                for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
                i += j;
                if ( om == end ) break;
@@ -189,7 +190,7 @@ void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
                ibuf[0] = '\0';
        }
        for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
-               if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) continue;
+               if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
                for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) {
                        if ( !sys ) {
                                idx.bv_len = sprintf(idx.bv_val, "{%d}", i );