]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_prep.c
More system schema checks
[openldap] / servers / slapd / schema_prep.c
index 079026f7ad2a9e2249cbce17bd90339ca5eb252b..2c41c0d368954ddbf59dc7bbaf839fa8424bd7f2 100644 (file)
@@ -116,7 +116,10 @@ structuralObjectClassMatch(
 }
 
 static ObjectClassSchemaCheckFN rootDseObjectClass;
+static ObjectClassSchemaCheckFN aliasObjectClass;
+static ObjectClassSchemaCheckFN referralObjectClass;
 static ObjectClassSchemaCheckFN subentryObjectClass;
+static ObjectClassSchemaCheckFN dynamicObjectClass;
 
 static struct slap_schema_oc_map {
        char *ssom_name;
@@ -137,43 +140,51 @@ static struct slap_schema_oc_map {
                        "DESC 'RFC2256: an alias' "
                        "SUP top STRUCTURAL "
                        "MUST aliasedObjectName )",
-               0, offsetof(struct slap_internal_schema, si_oc_alias) },
+               aliasObjectClass,
+               offsetof(struct slap_internal_schema, si_oc_alias) },
        { "referral", "( 2.16.840.1.113730.3.2.6 NAME 'referral' "
                        "DESC 'namedref: named subordinate referral' "
                        "SUP top STRUCTURAL MUST ref )",
-               0, offsetof(struct slap_internal_schema, si_oc_referral) },
+               referralObjectClass,
+               offsetof(struct slap_internal_schema, si_oc_referral) },
        { "LDAProotDSE", "( 1.3.6.1.4.1.4203.1.4.1 "
                        "NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) "
                        "DESC 'OpenLDAP Root DSE object' "
-                       "SUP top STRUCTURAL MAY cn )", rootDseObjectClass,
+                       "SUP top STRUCTURAL MAY cn )",
+               rootDseObjectClass,
                offsetof(struct slap_internal_schema, si_oc_rootdse) },
        { "subentry", "( 2.5.20.0 NAME 'subentry' "
                        "SUP top STRUCTURAL "
                        "MUST ( cn $ subtreeSpecification ) )",
-               0, offsetof(struct slap_internal_schema, si_oc_subentry) },
+               subentryObjectClass,
+               offsetof(struct slap_internal_schema, si_oc_subentry) },
        { "subschema", "( 2.5.20.1 NAME 'subschema' "
                "DESC 'RFC2252: controlling subschema (sub)entry' "
                "AUXILIARY "
                "MAY ( dITStructureRules $ nameForms $ ditContentRules $ "
                        "objectClasses $ attributeTypes $ matchingRules $ "
-                       "matchingRuleUse ) )", subentryObjectClass,
+                       "matchingRuleUse ) )",
+               subentryObjectClass,
                offsetof(struct slap_internal_schema, si_oc_subschema) },
        { "collectiveAttributes", "( 2.5.20.2 "
                        "NAME 'collectiveAttributes' "
-                       "AUXILIARY )", subentryObjectClass,
+                       "AUXILIARY )",
+               subentryObjectClass,
                offsetof(struct slap_internal_schema, si_oc_collectiveAttributes) },
        { "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
                        "NAME 'dynamicObject' "
                        "DESC 'RFC2589: Dynamic Object' "
                        "SUP top AUXILIARY )",
-               0,
+               dynamicObjectClass,
                offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
        { NULL, 0 }
 };
 
 static AttributeTypeSchemaCheckFN rootDseAttribute;
-static AttributeTypeSchemaCheckFN subentryAttribute;
+static AttributeTypeSchemaCheckFN aliasAttribute;
 static AttributeTypeSchemaCheckFN referralAttribute;
+static AttributeTypeSchemaCheckFN subentryAttribute;
+static AttributeTypeSchemaCheckFN dynamicAttribute;
 
 static struct slap_schema_ad_map {
        char *ssam_name;
@@ -407,7 +418,7 @@ static struct slap_schema_ad_map {
                        "DESC 'RFC2256: name of aliased object' "
                        "EQUALITY distinguishedNameMatch "
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
-               NULL, NULL, NULL, NULL,
+               aliasAttribute, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
        { "ref", "( 2.16.840.1.113730.3.1.34 NAME 'ref' "
                        "DESC 'namedref: subordinate referral URL' "
@@ -447,7 +458,7 @@ static struct slap_schema_ad_map {
                        "DESC 'RFC2589: entry time-to-live' "
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE "
                        "NO-USER-MODIFICATION USAGE dSAOperation )",
-               NULL, NULL, NULL, NULL,
+               dynamicAttribute, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_entryTtl) },
        { "dynamicSubtrees", "( 1.3.6.1.4.1.1466.101.119.4 "
                        "NAME 'dynamicSubtrees' "
@@ -457,7 +468,7 @@ static struct slap_schema_ad_map {
                rootDseAttribute, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },
 
-       /* userApplication attributes */
+       /* userApplication attributes (which system schema depends upon) */
        { "distinguishedName", "( 2.5.4.49 NAME 'distinguishedName' "
                        "DESC 'RFC2256: common supertype of DN attributes' "
                        "EQUALITY distinguishedNameMatch "
@@ -476,7 +487,6 @@ static struct slap_schema_ad_map {
                        "SUP name )",
                NULL, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_cn) },
-
        { "userPassword", "( 2.5.4.35 NAME 'userPassword' "
                        "DESC 'RFC2256/2307: password of user' "
                        "EQUALITY octetStringMatch "
@@ -720,6 +730,7 @@ static int rootDseObjectClass (
        char *textbuf, size_t textlen )
 {
        *text = textbuf;
+
        if( e->e_nname.bv_len ) {
                snprintf( textbuf, textlen,
                        "objectClass \"%s\" only allowed in the root DSE",
@@ -732,6 +743,44 @@ static int rootDseObjectClass (
        return LDAP_SUCCESS;
 }
 
+static int aliasObjectClass (
+       Backend *be,
+       Entry *e,
+       ObjectClass *oc,
+       const char** text,
+       char *textbuf, size_t textlen )
+{
+       *text = textbuf;
+
+       if( !SLAP_ALIASES(be) ) {
+               snprintf( textbuf, textlen,
+                       "objectClass \"%s\" not supported in context",
+                       oc->soc_oid );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int referralObjectClass (
+       Backend *be,
+       Entry *e,
+       ObjectClass *oc,
+       const char** text,
+       char *textbuf, size_t textlen )
+{
+       *text = textbuf;
+
+       if( !SLAP_REFERRALS(be) ) {
+               snprintf( textbuf, textlen,
+                       "objectClass \"%s\" not supported in context",
+                       oc->soc_oid );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       return LDAP_SUCCESS;
+}
+
 static int subentryObjectClass (
        Backend *be,
        Entry *e,
@@ -739,12 +788,41 @@ static int subentryObjectClass (
        const char** text,
        char *textbuf, size_t textlen )
 {
-       if( !is_entry_subentry( e ) ) {
+       *text = textbuf;
+
+       if( !SLAP_SUBENTRIES(be) ) {
+               snprintf( textbuf, textlen,
+                       "objectClass \"%s\" not supported in context",
+                       oc->soc_oid );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( oc != slap_schema.si_oc_subentry && !is_entry_subentry( e ) ) {
                snprintf( textbuf, textlen,
                        "objectClass \"%s\" only allowed in subentries",
                        oc->soc_oid );
                return LDAP_OBJECT_CLASS_VIOLATION;
        }
+
+       return LDAP_SUCCESS;
+}
+
+static int dynamicObjectClass (
+       Backend *be,
+       Entry *e,
+       ObjectClass *oc,
+       const char** text,
+       char *textbuf, size_t textlen )
+{
+       *text = textbuf;
+
+       if( !SLAP_DYNAMIC(be) ) {
+               snprintf( textbuf, textlen,
+                       "objectClass \"%s\" not supported in context",
+                       oc->soc_oid );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
        return LDAP_SUCCESS;
 }
 
@@ -756,6 +834,7 @@ static int rootDseAttribute (
        char *textbuf, size_t textlen )
 {
        *text = textbuf;
+
        if( e->e_nname.bv_len ) {
                snprintf( textbuf, textlen,
                        "attribute \"%s\" only allowed in the root DSE",
@@ -768,7 +847,7 @@ static int rootDseAttribute (
        return LDAP_SUCCESS;
 }
 
-static int subentryAttribute (
+static int aliasAttribute (
        Backend *be,
        Entry *e,
        Attribute *attr,
@@ -776,9 +855,17 @@ static int subentryAttribute (
        char *textbuf, size_t textlen )
 {
        *text = textbuf;
-       if( !is_entry_subentry( e ) ) {
+
+       if( !SLAP_ALIASES(be) ) {
                snprintf( textbuf, textlen,
-                       "attribute \"%s\" only allowed in the subentry",
+                       "attribute \"%s\" not supported in context",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( !is_entry_alias( e ) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" only allowed in the alias",
                        attr->a_desc->ad_cname.bv_val );
                return LDAP_OBJECT_CLASS_VIOLATION;
        }
@@ -794,6 +881,14 @@ static int referralAttribute (
        char *textbuf, size_t textlen )
 {
        *text = textbuf;
+
+       if( !SLAP_REFERRALS(be) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" not supported in context",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
        if( !is_entry_referral( e ) ) {
                snprintf( textbuf, textlen,
                        "attribute \"%s\" only allowed in the referral",
@@ -803,3 +898,55 @@ static int referralAttribute (
 
        return LDAP_SUCCESS;
 }
+
+static int subentryAttribute (
+       Backend *be,
+       Entry *e,
+       Attribute *attr,
+       const char** text,
+       char *textbuf, size_t textlen )
+{
+       *text = textbuf;
+
+       if( !SLAP_SUBENTRIES(be) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" not supported in context",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( !is_entry_subentry( e ) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" only allowed in the subentry",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int dynamicAttribute (
+       Backend *be,
+       Entry *e,
+       Attribute *attr,
+       const char** text,
+       char *textbuf, size_t textlen )
+{
+       *text = textbuf;
+
+       if( !SLAP_DYNAMIC(be) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" not supported in context",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( !is_entry_dynamicObject( e ) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" only allowed in dynamic object",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       return LDAP_SUCCESS;
+}