From: Howard Chu Date: Thu, 7 Apr 2005 05:23:23 +0000 (+0000) Subject: On add, sort attributes in schema order to enforce config sequencing X-Git-Tag: OPENLDAP_AC_BP~991 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=15fe667281dfe592297d8403e82ce03ef490452d;p=openldap On add, sort attributes in schema order to enforce config sequencing --- diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index d3f28a9d66..3014e13c2d 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -65,6 +65,7 @@ typedef struct CfOcInfo { struct berval *co_name; ConfigTable *co_table; ConfigType co_type; + ObjectClass *co_oc; } CfOcInfo; typedef struct CfEntryInfo { @@ -264,7 +265,8 @@ ConfigTable config_back_cf_table[] = { &config_generic, "( OLcfgAt:9 NAME 'olcBackend' " "DESC 'A type of backend' " "EQUALITY caseIgnoreMatch " - "SYNTAX OMsDirectoryString X-ORDERED 'SIBLINGS' )", NULL, NULL }, + "SYNTAX OMsDirectoryString SINGLE-VALUE X-ORDERED 'SIBLINGS' )", + NULL, NULL }, { "concurrency", "level", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_CONCUR, &config_generic, "( OLcfgAt:10 NAME 'olcConcurrency' " "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, @@ -277,7 +279,7 @@ ConfigTable config_back_cf_table[] = { { "database", "type", 2, 2, 0, ARG_MAGIC|CFG_DATABASE, &config_generic, "( OLcfgAt:13 NAME 'olcDatabase' " "DESC 'The backend type for a database instance' " - "SUP olcBackend X-ORDERED 'SIBLINGS' )", NULL, NULL }, + "SUP olcBackend SINGLE-VALUE X-ORDERED 'SIBLINGS' )", NULL, NULL }, { "defaultSearchBase", "dn", 2, 2, 0, ARG_PRE_BI|ARG_PRE_DB|ARG_DN|ARG_MAGIC, &config_search_base, "( OLcfgAt:14 NAME 'olcDefaultSearchBase' " "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL }, @@ -363,7 +365,7 @@ ConfigTable config_back_cf_table[] = { "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL }, { "overlay", "overlay", 2, 2, 0, ARG_MAGIC, &config_overlay, "( OLcfgAt:34 NAME 'olcOverlay' " - "SUP olcDatabase X-ORDERED 'SIBLINGS' )", NULL, NULL }, + "SUP olcDatabase SINGLE-VALUE X-ORDERED 'SIBLINGS' )", NULL, NULL }, { "password-crypt-salt-format", "salt", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_SALT, &config_generic, "( OLcfgAt:35 NAME 'olcPasswordCryptSaltFormat' " "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, @@ -587,26 +589,27 @@ static ConfigOCs cf_ocs[] = { "DESC 'OpenLDAP Global configuration options' " "SUP olcConfig STRUCTURAL " "MAY ( cn $ olcConfigFile $ olcConfigDir $ olcAllows $ olcArgsFile $ " - "olcAttributeOptions $ olcAttributeTypes $ olcAuthIDRewrite $ " + "olcAttributeOptions $ olcAuthIDRewrite $ " "olcAuthzPolicy $ olcAuthzRegexp $ olcConcurrency $ " "olcConnMaxPending $ olcConnMaxPendingAuth $ olcDefaultSearchBase $ " - "olcDisallows $ olcDitContentRules $ olcGentleHUP $ olcIdleTimeout $ " + "olcDisallows $ olcGentleHUP $ olcIdleTimeout $ " "olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ " "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcLocalSSF $ " - "olcLogLevel $ olcModulePath $ olcObjectClasses $ " - "olcObjectIdentifier $ " + "olcLogLevel $ olcModulePath $ " "olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ " - "olcPlugin $ olcPluginLogFile $ olcReadOnly $ olcReferral $ " + "olcPluginLogFile $ olcReadOnly $ olcReferral $ " "olcReplicaPidFile $ olcReplicaArgsFile $ olcReplicationInterval $ " "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ " "olcRootDSE $ olcRootPW $ " "olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ " - "olcSchemaCheck $ olcSchemaDN $ olcSecurity $ olcSizeLimit $ " + "olcSchemaCheck $ olcSecurity $ olcSizeLimit $ " "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcSrvtab $ " "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ " "olcTLSCACertificatePath $ olcTLSCertificateFile $ " "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ " - "olcTLSRandFile $ olcTLSVerifyClient ) )", Cft_Global, &cfOc_global }, + "olcTLSRandFile $ olcTLSVerifyClient $ " + "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ " + "olcDitContentRules ) )", Cft_Global, &cfOc_global }, { "( OLcfgOc:3 " "NAME 'olcSchemaConfig' " "DESC 'OpenLDAP schema object' " @@ -889,7 +892,7 @@ config_generic(ConfigArgs *c) { rc = 1; break; case CFG_CONCUR: - ldap_pvt_thread_set_concurrency(c); + ldap_pvt_thread_set_concurrency(c->value_int); break; } @@ -2774,7 +2777,8 @@ config_register_schema(ConfigTable *ct, ConfigOCs *ocs) { for (i=0; ocs[i].def; i++) { if ( ocs[i].oc ) { co = ch_malloc( sizeof(CfOcInfo) ); - co->co_name = &(*ocs[i].oc)->soc_cname; + 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 ); @@ -2942,6 +2946,64 @@ sort_vals( Attribute *a ) return 0; } +/* Sort the attributes of the entry according to the order defined + * in the objectclass, with required attributes occurring before + * allowed attributes. For any attributes with sequencing dependencies + * (e.g., rootDN must be defined after suffix) the objectclass must + * list the attributes in the desired sequence. + */ +static void +sort_attrs( Entry *e, CfOcInfo **colst, int nocs ) +{ + Attribute *a, *head = NULL, *tail = NULL, **prev; + int i, j; + + for (i=0; ico_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) { + if ( a->a_desc == at[j]->sat_ad ) { + *prev = a->a_next; + if (!head) { + head = a; + tail = a; + } else { + tail->a_next = a; + tail = a; + } + break; + } + } + } + } + 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) { + if ( a->a_desc == at[j]->sat_ad ) { + *prev = a->a_next; + if (!head) { + head = a; + tail = a; + } else { + tail->a_next = a; + tail = a; + } + break; + } + } + } + } + } + if ( tail ) { + tail->a_next = e->e_attrs; + e->e_attrs = head; + } +} + static int check_attr( ConfigTable *ct, ConfigArgs *ca, Attribute *a ) { @@ -3178,6 +3240,8 @@ config_add_internal( CfBackInfo *cfb, Entry *e, SlapReply *rs, int *renum ) break; } + sort_attrs( e, colst, nocs ); + /* Parse all the values and check for simple syntax errors before * performing any set actions. */