struct CfEntryInfo *ce_sibs;
struct CfEntryInfo *ce_kids;
Entry *ce_entry;
- ConfigTable *ce_table;
+ BackendInfo *ce_bi;
+ BackendDB *ce_be;
} CfEntryInfo;
typedef struct {
CfEntryInfo *cb_root;
} CfBackInfo;
+static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
+ *cfAd_include;
+
+static ObjectClass *cfOc_global, *cfOc_backend, *cfOc_database,
+ *cfOc_include, *cfOc_overlay;
+
+static struct oc_info {
+ char *def;
+ ObjectClass **oc;
+} cf_ocs[] = {
+ { "( OLcfgOc:1 "
+ "NAME 'olcConfig' "
+ "DESC 'OpenLDAP configuration object' "
+ "ABSTRACT SUP top "
+ "MAY ( cn $ olcConfigFile ) )", NULL },
+ { "( OLcfgOc:3 "
+ "NAME 'olcGlobal' "
+ "DESC 'OpenLDAP Global configuration options' "
+ "SUP olcConfig STRUCTURAL "
+ "MAY ( olcAccess $ olcAllows $ olcArgsFile $ olcAttributeOptions $ "
+ "olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ "
+ "olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ "
+ "olcDefaultSearchBase $ olcDisallows $ olcGentleHUP $ "
+ "olcIdleTimeout $ olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ "
+ "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcLocalSSF $ "
+ "olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectIdentifier $ "
+ "olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ "
+ "olcPlugin $ olcPluginLogFile $ olcReadOnly $ olcReferral $ "
+ "olcReplicaPidFile $ olcReplicaArgsFile $ olcReplicationInterval $ "
+ "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
+ "olcRootDSE $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
+ "olcSchemaCheck $ olcSchemaDN $ olcSecurity $ olcSizeLimit $ "
+ "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcSrvtab $ "
+ "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
+ "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
+ "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
+ "olcTLSRandFile $ olcTLSVerifyClient ) )", &cfOc_global },
+ { "( OLcfgOc:4 "
+ "NAME 'olcBackendConfig' "
+ "DESC 'OpenLDAP Backend-specific options' "
+ "SUP olcConfig STRUCTURAL "
+ "MAY ( olcBackend ) )", &cfOc_backend },
+ { "( OLcfgOc:5 "
+ "NAME 'olcDatabaseConfig' "
+ "DESC 'OpenLDAP Database-specific options' "
+ "SUP olcConfig STRUCTURAL "
+ "MAY ( olcAccess $ olcDatabase $ olcLastMod $ olcLimits $ "
+ "olcMaxDerefDepth $ olcReadOnly $ olcReplica $ olcReplogFile $ "
+ "olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ olcSchemaDN $ "
+ "olcSecurity $ olcSizeLimit $ olcSuffix $ olcSyncrepl $ "
+ "olcTimeLimit $ olcUpdateDN $ olcUpdateRef ) )", &cfOc_database },
+ { "( OLcfgOc:6 "
+ "NAME 'olcIncludeFile' "
+ "DESC 'OpenLDAP configuration include file' "
+ "SUP olcConfig STRUCTURAL "
+ "MAY ( olcInclude $ olcModuleLoad $ olcModulePath $ olcRootDSE ) )",
+ &cfOc_include },
+ { "( OLcfgOc:7 "
+ "NAME 'olcOverlayConfig' "
+ "DESC 'OpenLDAP Overlay-specific options' "
+ "SUP olcConfig STRUCTURAL "
+ "MAY ( olcOverlay ) )", &cfOc_overlay },
+ { NULL, NULL }
+};
+
static int
config_back_bind( Operation *op, SlapReply *rs )
{
return e;
}
+#define NO_TABLE 0
+#define BI_TABLE 1
+#define BE_TABLE 2
+
static int
-config_build_entry( Entry *e, void *private, char *oc, struct berval *rdn )
+config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc,
+ struct berval *rdn, ConfigTable *ct, int table )
{
struct berval vals[2];
struct berval ad_name;
AttributeDescription *ad = NULL;
- int rc;
+ int rc, i;
char *ptr;
const char *text;
+ AttributeType **at;
BER_BVZERO( &vals[1] );
- ber_str2bv( oc, 0, 0, &vals[0] );
+ vals[0] = oc->soc_cname;
attr_merge(e, slap_schema.si_ad_objectClass, vals, NULL );
ptr = strchr(rdn->bv_val, '=');
ad_name.bv_val = rdn->bv_val;
vals[0].bv_val = ptr+1;
vals[0].bv_len = rdn->bv_len - (vals[0].bv_val - rdn->bv_val);
attr_merge(e, ad, vals, NULL );
+
+ for (at=oc->soc_allowed;*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)
+ break;
+ }
+ rc = config_get_vals(&ct[i], c);
+ if (rc == LDAP_SUCCESS) {
+ attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
+ ber_bvarray_free( c->rvalue_nvals );
+ ber_bvarray_free( c->rvalue_vals );
+ }
+ }
+
+ 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) {
+ attr_merge(e, ct->ad, c->rvalue_vals, c->rvalue_nvals);
+ }
+ }
+ }
+
return 0;
}
+static CfEntryInfo *
+config_build_includes( ConfigArgs *c, Entry *parent )
+{
+ Entry *e;
+ int i;
+ ConfigFile *cf = (ConfigFile *)c->line;
+ CfEntryInfo *ce, *ceparent, *ceprev;
+
+ ceparent = parent->e_private;
+
+ 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{%d}", i);
+ e = config_alloc_entry( &parent->e_nname, &c->value_dn );
+ c->line = (char *)cf;
+ config_build_entry( c, e, cfOc_include, &c->value_dn,
+ c->bi->bi_cf_table, NO_TABLE );
+ ce = e->e_private;
+ if ( !ceparent->ce_kids ) {
+ ceparent->ce_kids = ce;
+ } else {
+ ceprev->ce_sibs = ce;
+ }
+ ceprev = ce;
+ if ( cf->c_kids ) {
+ c->line = (char *)cf->c_kids;
+ config_build_includes( c, e );
+ }
+ }
+ return ce;
+}
+
static int
config_back_db_open( BackendDB *be )
{
struct berval rdn;
Entry *e, *parent;
CfEntryInfo *ce, *ceparent, *ceprev;
- int i, buflen = 0;
- char *buf = NULL;
+ int i, rc;
BackendInfo *bi;
BackendDB *bptr;
+ ConfigArgs c;
+ ConfigTable *ct;
/* create root of tree */
ber_str2bv( CONFIG_DN, STRLENOF( CONFIG_DN ), 0, &rdn );
e = config_alloc_entry( NULL, &rdn );
ce = e->e_private;
- ce->ce_table = be->bd_info->bi_cf_table;
cfb->cb_root = ce;
-
- config_build_entry( e, be->be_private, "olcGlobal", &rdn );
+ c.be = be;
+ c.bi = be->bd_info;
+ c.line = (char *)cfb->cb_config;
+ ct = c.bi->bi_cf_table;
+ config_build_entry( &c, e, cfOc_global, &rdn, ct, NO_TABLE );
parent = e;
ceparent = ce;
+ /* Create includeFile nodes... */
+ if ( cfb->cb_config->c_kids ) {
+ c.line = (char *)cfb->cb_config->c_kids;
+ ceprev = config_build_includes( &c, parent );
+ }
+
/* Create backend nodes. Skip if they don't provide a cf_table.
* There usually aren't any of these.
*/
+
+ c.line = 0;
bi = backendInfo;
for (i=0; i<nBackendInfo; i++, bi++) {
if (!bi->bi_cf_table) continue;
if (!bi->bi_private) continue;
- if ( buflen < STRLENOF("olcbackend=")+strlen(bi->bi_type)+1) {
- buflen = STRLENOF("olcbackend=") + strlen(bi->bi_type)+1;
- buf = realloc(buf, buflen);
- }
- rdn.bv_val = buf;
- rdn.bv_len = sprintf(buf, "olcBackend=%s", bi->bi_type);
+ 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( &parent->e_nname, &rdn );
ce = e->e_private;
- ce->ce_table = bi->bi_cf_table;
- config_build_entry( e, bi->bi_private, "olcBackendConfig",
- &rdn );
+ ce->ce_bi = bi;
+ c.bi = bi;
+ config_build_entry( &c, e, cfOc_backend, &rdn, ct, BI_TABLE );
if ( !ceparent->ce_kids ) {
ceparent->ce_kids = ce;
} else {
/* Create database nodes... */
for (i=0; i<nBackendDB; i++) {
+ slap_overinfo *oi = NULL;
if ( i == 0 ) {
bptr = frontendDB;
} else {
bptr = &backendDB[i];
}
- bi = bptr->bd_info;
- if ( buflen < STRLENOF("olcdatabase={xxxxxxxx}")+strlen(bi->bi_type)+1) {
- buflen = STRLENOF("olcdatabase={xxxxxxxx}")+strlen(bi->bi_type)+1;
- buf = realloc(buf, buflen);
+ if ( overlay_is_over( bptr )) {
+ oi = bptr->bd_info->bi_private;
+ bi = oi->oi_orig;
+ } else {
+ bi = bptr->bd_info;
}
- rdn.bv_val = buf;
- rdn.bv_len = sprintf(buf, "olcDatabase={%0x}%s", i, bi->bi_type);
+ rdn.bv_val = c.log;
+ rdn.bv_len = sprintf(rdn.bv_val, "%s={%0x}%s", cfAd_database->ad_cname.bv_val,
+ i, bi->bi_type);
e = config_alloc_entry( &parent->e_nname, &rdn );
ce = e->e_private;
- ce->ce_table = bptr->be_cf_table;
- config_build_entry( e, bptr->be_private, "olcDatabaseConfig",
- &rdn );
+ c.be = bptr;
+ c.bi = bi;
+ ce->ce_be = c.be;
+ ce->ce_bi = c.bi;
+ config_build_entry( &c, e, cfOc_database, &rdn, ct, BE_TABLE );
if ( !ceparent->ce_kids ) {
ceparent->ce_kids = ce;
} else {
}
ceprev = ce;
/* 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={%0x}%s",
+ cfAd_overlay->ad_cname.bv_val, j, on->on_bi.bi_type );
+ oe = config_alloc_entry( &e->e_nname, &rdn );
+ ce = oe->e_private;
+ c.be = bptr;
+ c.bi = &on->on_bi;
+ ce->ce_be = c.be;
+ ce->ce_bi = c.bi;
+ config_build_entry( &c, oe, cfOc_overlay, &rdn, ct, BI_TABLE );
+ if ( !opar->ce_kids ) {
+ opar->ce_kids = ce;
+ } else {
+ oprev->ce_sibs = ce;
+ }
+ oprev = ce;
+ }
+ }
}
- /* Create includeFile nodes... */
return 0;
}
return 0;
}
-void config_back_init( ConfigFile *cfp, ConfigTable *ct )
+static struct {
+ char *name;
+ AttributeDescription **desc;
+ AttributeDescription *sub;
+} ads[] = {
+ { "attribute", NULL, NULL },
+ { "backend", &cfAd_backend, NULL },
+ { "database", &cfAd_database, NULL },
+ { "ditcontentrule", NULL, NULL },
+ { "include", &cfAd_include, NULL },
+ { "objectclass", NULL, NULL },
+ { "overlay", &cfAd_overlay, NULL },
+ { NULL, NULL, NULL }
+};
+
+int config_back_init( ConfigFile *cfp, ConfigTable *ct )
{
BackendInfo bi = {0};
BackendDB *be;
struct berval dn;
CfBackInfo *cfb;
+ int i;
bi.bi_type = "config";
bi.bi_init = config_back_initialize;
cfb = ch_calloc( 1, sizeof(CfBackInfo));
cfb->cb_config = cfp;
be->be_private = cfb;
+
+ /* set up the notable AttributeDescriptions */
+ ads[0].sub = slap_schema.si_ad_attributeTypes;
+ ads[3].sub = slap_schema.si_ad_ditContentRules;
+ ads[5].sub = slap_schema.si_ad_objectClasses;
+
+ i = 0;
+ for (;ct->name;ct++) {
+ if (strcmp(ct->name, ads[i].name)) continue;
+ if (ads[i].sub) {
+ ct->ad = ads[i].sub;
+ } else {
+ *ads[i].desc = ct->ad;
+ }
+ i++;
+ if (!ads[i].name) break;
+ }
+
+ /* set up the objectclasses */
+ for (i=0;cf_ocs[i].def;i++) {
+ LDAPObjectClass *oc;
+ int code;
+ const char *err;
+
+ oc = ldap_str2objectclass( cf_ocs[i].def, &code, &err,
+ LDAP_SCHEMA_ALLOW_ALL );
+ if ( !oc ) {
+ fprintf( stderr, "config_back_init: objectclass \"%s\": %s, %s\n",
+ cf_ocs[i].def, ldap_scherr2str(code), err );
+ return code;
+ }
+ code = oc_add(oc,0,&err);
+ if ( code ) {
+ fprintf( stderr, "config_back_init: objectclass \"%s\": %s, %s\n",
+ cf_ocs[i].def, scherr2str(code), err );
+ return code;
+ }
+ if ( cf_ocs[i].oc ) {
+ *cf_ocs[i].oc = oc_find(oc->oc_names[0]);
+ }
+ ldap_memfree(oc);
+ }
+ return 0;
}