Back to index

openldap  2.4.31
schema_prep.c
Go to the documentation of this file.
00001 /* schema_prep.c - load builtin schema */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 1998-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 
00019 #include <stdio.h>
00020 
00021 #include <ac/ctype.h>
00022 #include <ac/string.h>
00023 #include <ac/socket.h>
00024 
00025 #include "slap.h"
00026 
00027 #define OCDEBUG 0
00028 
00029 int schema_init_done = 0;
00030 
00031 struct slap_internal_schema slap_schema;
00032 
00033 static int
00034 oidValidate(
00035        Syntax *syntax,
00036        struct berval *in )
00037 {
00038        struct berval val = *in;
00039 
00040        if( val.bv_len == 0 ) {
00041               /* disallow empty strings */
00042               return LDAP_INVALID_SYNTAX;
00043        }
00044 
00045        if( DESC_LEADCHAR( val.bv_val[0] ) ) {
00046               val.bv_val++;
00047               val.bv_len--;
00048               if ( val.bv_len == 0 ) return LDAP_SUCCESS;
00049 
00050               while( DESC_CHAR( val.bv_val[0] ) ) {
00051                      val.bv_val++;
00052                      val.bv_len--;
00053 
00054                      if ( val.bv_len == 0 ) return LDAP_SUCCESS;
00055               }
00056 
00057        } else {
00058               int sep = 0;
00059               while( OID_LEADCHAR( val.bv_val[0] ) ) {
00060                      val.bv_val++;
00061                      val.bv_len--;
00062 
00063                      if ( val.bv_val[-1] != '0' ) {
00064                             while ( OID_LEADCHAR( val.bv_val[0] )) {
00065                                    val.bv_val++;
00066                                    val.bv_len--;
00067                             }
00068                      }
00069 
00070                      if( val.bv_len == 0 ) {
00071                             if( sep == 0 ) break;
00072                             return LDAP_SUCCESS;
00073                      }
00074 
00075                      if( !OID_SEPARATOR( val.bv_val[0] )) break;
00076 
00077                      sep++;
00078                      val.bv_val++;
00079                      val.bv_len--;
00080               }
00081        }
00082 
00083        return LDAP_INVALID_SYNTAX;
00084 }
00085 
00086 
00087 static int objectClassPretty(
00088        Syntax *syntax,
00089        struct berval *in,
00090        struct berval *out,
00091        void *ctx )
00092 {
00093        ObjectClass *oc;
00094 
00095        if( oidValidate( NULL, in )) return LDAP_INVALID_SYNTAX;
00096 
00097        oc = oc_bvfind( in );
00098        if( oc == NULL ) return LDAP_INVALID_SYNTAX;
00099 
00100        ber_dupbv_x( out, &oc->soc_cname, ctx );
00101        return LDAP_SUCCESS;
00102 }
00103 
00104 static int
00105 attributeTypeMatch(
00106        int *matchp,
00107        slap_mask_t flags,
00108        Syntax *syntax,
00109        MatchingRule *mr,
00110        struct berval *value,
00111        void *assertedValue )
00112 {
00113        struct berval *a = (struct berval *) assertedValue;
00114        AttributeType *at = at_bvfind( value );
00115        AttributeType *asserted = at_bvfind( a );
00116 
00117        if( asserted == NULL ) {
00118               if( OID_LEADCHAR( *a->bv_val ) ) {
00119                      /* OID form, return FALSE */
00120                      *matchp = 1;
00121                      return LDAP_SUCCESS;
00122               }
00123 
00124               /* desc form, return undefined */
00125               return LDAP_INVALID_SYNTAX;
00126        }
00127 
00128        if ( at == NULL ) {
00129               /* unrecognized stored value */
00130               return LDAP_INVALID_SYNTAX;
00131        }
00132 
00133        *matchp = ( asserted != at );
00134        return LDAP_SUCCESS;
00135 }
00136 
00137 static int
00138 matchingRuleMatch(
00139        int *matchp,
00140        slap_mask_t flags,
00141        Syntax *syntax,
00142        MatchingRule *mr,
00143        struct berval *value,
00144        void *assertedValue )
00145 {
00146        struct berval *a = (struct berval *) assertedValue;
00147        MatchingRule *mrv = mr_bvfind( value );
00148        MatchingRule *asserted = mr_bvfind( a );
00149 
00150        if( asserted == NULL ) {
00151               if( OID_LEADCHAR( *a->bv_val ) ) {
00152                      /* OID form, return FALSE */
00153                      *matchp = 1;
00154                      return LDAP_SUCCESS;
00155               }
00156 
00157               /* desc form, return undefined */
00158               return LDAP_INVALID_SYNTAX;
00159        }
00160 
00161        if ( mrv == NULL ) {
00162               /* unrecognized stored value */
00163               return LDAP_INVALID_SYNTAX;
00164        }
00165 
00166        *matchp = ( asserted != mrv );
00167        return LDAP_SUCCESS;
00168 }
00169 
00170 static int
00171 objectClassMatch(
00172        int *matchp,
00173        slap_mask_t flags,
00174        Syntax *syntax,
00175        MatchingRule *mr,
00176        struct berval *value,
00177        void *assertedValue )
00178 {
00179        struct berval *a = (struct berval *) assertedValue;
00180        ObjectClass *oc = oc_bvfind( value );
00181        ObjectClass *asserted = oc_bvfind( a );
00182 
00183        if( asserted == NULL ) {
00184               if( OID_LEADCHAR( *a->bv_val ) ) {
00185                      /* OID form, return FALSE */
00186                      *matchp = 1;
00187                      return LDAP_SUCCESS;
00188               }
00189 
00190               /* desc form, return undefined */
00191               return LDAP_INVALID_SYNTAX;
00192        }
00193 
00194        if ( oc == NULL ) {
00195               /* unrecognized stored value */
00196               return LDAP_INVALID_SYNTAX;
00197        }
00198 
00199        *matchp = ( asserted != oc );
00200        return LDAP_SUCCESS;
00201 }
00202 
00203 static int
00204 objectSubClassMatch(
00205        int *matchp,
00206        slap_mask_t flags,
00207        Syntax *syntax,
00208        MatchingRule *mr,
00209        struct berval *value,
00210        void *assertedValue )
00211 {
00212        struct berval *a = (struct berval *) assertedValue;
00213        ObjectClass *oc = oc_bvfind( value );
00214        ObjectClass *asserted = oc_bvfind( a );
00215 
00216        if( asserted == NULL ) {
00217               if( OID_LEADCHAR( *a->bv_val ) ) {
00218                      /* OID form, return FALSE */
00219                      *matchp = 1;
00220                      return LDAP_SUCCESS;
00221               }
00222 
00223               /* desc form, return undefined */
00224               return LDAP_INVALID_SYNTAX;
00225        }
00226 
00227        if ( oc == NULL ) {
00228               /* unrecognized stored value */
00229               return LDAP_INVALID_SYNTAX;
00230        }
00231 
00232        if( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX( flags ) ) {
00233               *matchp = ( asserted != oc );
00234        } else {
00235               *matchp = !is_object_subclass( asserted, oc );
00236        }
00237 
00238        return LDAP_SUCCESS;
00239 }
00240 
00241 static int objectSubClassIndexer( 
00242        slap_mask_t use,
00243        slap_mask_t mask,
00244        Syntax *syntax,
00245        MatchingRule *mr,
00246        struct berval *prefix,
00247        BerVarray values,
00248        BerVarray *keysp,
00249        void *ctx )
00250 {
00251        int rc, noc, i;
00252        BerVarray ocvalues;
00253        ObjectClass **socs;
00254        
00255        for( noc=0; values[noc].bv_val != NULL; noc++ ) {
00256               /* just count em */;
00257        }
00258 
00259        /* over allocate */
00260        socs = slap_sl_malloc( (noc+16) * sizeof( ObjectClass * ), ctx );
00261 
00262        /* initialize */
00263        for( i=0; i<noc; i++ ) {
00264               socs[i] = oc_bvfind( &values[i] );
00265        }
00266 
00267        /* expand values */
00268        for( i=0; i<noc; i++ ) {
00269               int j;
00270               ObjectClass *oc = socs[i];
00271               if( oc == NULL || oc->soc_sups == NULL ) continue;
00272               
00273               for( j=0; oc->soc_sups[j] != NULL; j++ ) {
00274                      int found = 0;
00275                      ObjectClass *sup = oc->soc_sups[j];
00276                      int k;
00277 
00278                      for( k=0; k<noc; k++ ) {
00279                             if( sup == socs[k] ) {
00280                                    found++;
00281                                    break;
00282                             }
00283                      }
00284 
00285                      if( !found ) {
00286                             socs = slap_sl_realloc( socs,
00287                                    sizeof( ObjectClass * ) * (noc+2), ctx );
00288 
00289                             assert( k == noc );
00290                             socs[noc++] = sup;
00291                      }
00292               }
00293        }
00294 
00295        ocvalues = slap_sl_malloc( sizeof( struct berval ) * (noc+1), ctx );
00296        /* copy values */
00297        for( i=0; i<noc; i++ ) {
00298               if ( socs[i] )
00299                      ocvalues[i] = socs[i]->soc_cname;
00300               else
00301                      ocvalues[i] = values[i];
00302        }
00303        BER_BVZERO( &ocvalues[i] );
00304 
00305        rc = octetStringIndexer( use, mask, syntax, mr,
00306               prefix, ocvalues, keysp, ctx );
00307 
00308        slap_sl_free( ocvalues, ctx );
00309        slap_sl_free( socs, ctx );
00310        return rc;
00311 }
00312 
00313 #define objectSubClassFilter octetStringFilter
00314 
00315 static ObjectClassSchemaCheckFN rootDseObjectClass;
00316 static ObjectClassSchemaCheckFN aliasObjectClass;
00317 static ObjectClassSchemaCheckFN referralObjectClass;
00318 static ObjectClassSchemaCheckFN subentryObjectClass;
00319 #ifdef LDAP_DYNAMIC_OBJECTS
00320 static ObjectClassSchemaCheckFN dynamicObjectClass;
00321 #endif
00322 
00323 static struct slap_schema_oc_map {
00324        char *ssom_name;
00325        char *ssom_defn;
00326        ObjectClassSchemaCheckFN *ssom_check;
00327        slap_mask_t ssom_flags;
00328        size_t ssom_offset;
00329 } oc_map[] = {
00330        { "top", "( 2.5.6.0 NAME 'top' "
00331                      "DESC 'top of the superclass chain' "
00332                      "ABSTRACT MUST objectClass )",
00333               0, 0, offsetof(struct slap_internal_schema, si_oc_top) },
00334        { "extensibleObject", "( 1.3.6.1.4.1.1466.101.120.111 "
00335                      "NAME 'extensibleObject' "
00336                      "DESC 'RFC4512: extensible object' "
00337                      "SUP top AUXILIARY )",
00338               0, SLAP_OC_OPERATIONAL,
00339               offsetof(struct slap_internal_schema, si_oc_extensibleObject) },
00340        { "alias", "( 2.5.6.1 NAME 'alias' "
00341                      "DESC 'RFC4512: an alias' "
00342                      "SUP top STRUCTURAL "
00343                      "MUST aliasedObjectName )",
00344               aliasObjectClass, SLAP_OC_ALIAS|SLAP_OC_OPERATIONAL,
00345               offsetof(struct slap_internal_schema, si_oc_alias) },
00346        { "referral", "( 2.16.840.1.113730.3.2.6 NAME 'referral' "
00347                      "DESC 'namedref: named subordinate referral' "
00348                      "SUP top STRUCTURAL MUST ref )",
00349               referralObjectClass, SLAP_OC_REFERRAL|SLAP_OC_OPERATIONAL,
00350               offsetof(struct slap_internal_schema, si_oc_referral) },
00351        { "LDAProotDSE", "( 1.3.6.1.4.1.4203.1.4.1 "
00352                      "NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) "
00353                      "DESC 'OpenLDAP Root DSE object' "
00354                      "SUP top STRUCTURAL MAY cn )",
00355               rootDseObjectClass, SLAP_OC_OPERATIONAL,
00356               offsetof(struct slap_internal_schema, si_oc_rootdse) },
00357        { "subentry", "( 2.5.17.0 NAME 'subentry' "
00358                      "DESC 'RFC3672: subentry' "
00359                      "SUP top STRUCTURAL "
00360                      "MUST ( cn $ subtreeSpecification ) )",
00361               subentryObjectClass, SLAP_OC_SUBENTRY|SLAP_OC_OPERATIONAL,
00362               offsetof(struct slap_internal_schema, si_oc_subentry) },
00363        { "subschema", "( 2.5.20.1 NAME 'subschema' "
00364               "DESC 'RFC4512: controlling subschema (sub)entry' "
00365               "AUXILIARY "
00366               "MAY ( dITStructureRules $ nameForms $ dITContentRules $ "
00367                      "objectClasses $ attributeTypes $ matchingRules $ "
00368                      "matchingRuleUse ) )",
00369               subentryObjectClass, SLAP_OC_OPERATIONAL,
00370               offsetof(struct slap_internal_schema, si_oc_subschema) },
00371 #ifdef LDAP_COLLECTIVE_ATTRIBUTES
00372        { "collectiveAttributeSubentry", "( 2.5.17.2 "
00373                      "NAME 'collectiveAttributeSubentry' "
00374                      "DESC 'RFC3671: collective attribute subentry' "
00375                      "AUXILIARY )",
00376               subentryObjectClass,
00377               SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
00378               offsetof( struct slap_internal_schema,
00379                      si_oc_collectiveAttributeSubentry) },
00380 #endif
00381 #ifdef LDAP_DYNAMIC_OBJECTS
00382        { "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
00383                      "NAME 'dynamicObject' "
00384                      "DESC 'RFC2589: Dynamic Object' "
00385                      "SUP top AUXILIARY )",
00386               dynamicObjectClass, SLAP_OC_DYNAMICOBJECT,
00387               offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
00388 #endif
00389        { "glue", "( 1.3.6.1.4.1.4203.666.3.4 "
00390                      "NAME 'glue' "
00391                      "DESC 'Glue Entry' "
00392                      "SUP top STRUCTURAL )",
00393               0, SLAP_OC_GLUE|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
00394               offsetof(struct slap_internal_schema, si_oc_glue) },
00395        { "syncConsumerSubentry", "( 1.3.6.1.4.1.4203.666.3.5 "
00396                      "NAME 'syncConsumerSubentry' "
00397                      "DESC 'Persistent Info for SyncRepl Consumer' "
00398                      "AUXILIARY "
00399                      "MAY syncreplCookie )",
00400               0, SLAP_OC_SYNCCONSUMERSUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
00401               offsetof(struct slap_internal_schema, si_oc_syncConsumerSubentry) },
00402        { "syncProviderSubentry", "( 1.3.6.1.4.1.4203.666.3.6 "
00403                      "NAME 'syncProviderSubentry' "
00404                      "DESC 'Persistent Info for SyncRepl Producer' "
00405                      "AUXILIARY "
00406                      "MAY contextCSN )",
00407               0, SLAP_OC_SYNCPROVIDERSUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
00408               offsetof(struct slap_internal_schema, si_oc_syncProviderSubentry) },
00409 
00410        { NULL, NULL, NULL, 0, 0 }
00411 };
00412 
00413 static AttributeTypeSchemaCheckFN rootDseAttribute;
00414 static AttributeTypeSchemaCheckFN aliasAttribute;
00415 static AttributeTypeSchemaCheckFN referralAttribute;
00416 static AttributeTypeSchemaCheckFN subentryAttribute;
00417 static AttributeTypeSchemaCheckFN administrativeRoleAttribute;
00418 #ifdef LDAP_DYNAMIC_OBJECTS
00419 static AttributeTypeSchemaCheckFN dynamicAttribute;
00420 #endif
00421 
00422 static struct slap_schema_ad_map {
00423        char *ssam_name;
00424        char *ssam_defn;
00425        AttributeTypeSchemaCheckFN *ssam_check;
00426        slap_mask_t ssam_flags;
00427        slap_syntax_validate_func *ssam_syn_validate;
00428        slap_syntax_transform_func *ssam_syn_pretty;
00429        slap_mr_convert_func *ssam_mr_convert;
00430        slap_mr_normalize_func *ssam_mr_normalize;
00431        slap_mr_match_func *ssam_mr_match;
00432        slap_mr_indexer_func *ssam_mr_indexer;
00433        slap_mr_filter_func *ssam_mr_filter;
00434        size_t ssam_offset;
00435 } ad_map[] = {
00436        { "objectClass", "( 2.5.4.0 NAME 'objectClass' "
00437                      "DESC 'RFC4512: object classes of the entity' "
00438                      "EQUALITY objectIdentifierMatch "
00439                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
00440               NULL, SLAP_AT_FINAL,
00441               oidValidate, objectClassPretty,
00442               NULL, NULL, objectSubClassMatch,
00443                      objectSubClassIndexer, objectSubClassFilter,
00444               offsetof(struct slap_internal_schema, si_ad_objectClass) },
00445 
00446        /* user entry operational attributes */
00447        { "structuralObjectClass", "( 2.5.21.9 NAME 'structuralObjectClass' "
00448                      "DESC 'RFC4512: structural object class of entry' "
00449                      "EQUALITY objectIdentifierMatch "
00450                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
00451                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00452               NULL, 0,
00453               oidValidate, objectClassPretty,
00454               NULL, NULL, objectSubClassMatch,
00455                      objectSubClassIndexer, objectSubClassFilter,
00456               offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) },
00457        { "createTimestamp", "( 2.5.18.1 NAME 'createTimestamp' "
00458                      "DESC 'RFC4512: time which object was created' "
00459                      "EQUALITY generalizedTimeMatch "
00460                      "ORDERING generalizedTimeOrderingMatch "
00461                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
00462                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00463               NULL, SLAP_AT_MANAGEABLE,
00464               NULL, NULL,
00465               NULL, NULL, NULL, NULL, NULL,
00466               offsetof(struct slap_internal_schema, si_ad_createTimestamp) },
00467        { "modifyTimestamp", "( 2.5.18.2 NAME 'modifyTimestamp' "
00468                      "DESC 'RFC4512: time which object was last modified' "
00469                      "EQUALITY generalizedTimeMatch "
00470                      "ORDERING generalizedTimeOrderingMatch "
00471                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
00472                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00473               NULL, SLAP_AT_MANAGEABLE,
00474               NULL, NULL,
00475               NULL, NULL, NULL, NULL, NULL,
00476               offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) },
00477        { "creatorsName", "( 2.5.18.3 NAME 'creatorsName' "
00478                      "DESC 'RFC4512: name of creator' "
00479                      "EQUALITY distinguishedNameMatch "
00480                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
00481                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00482               NULL, SLAP_AT_MANAGEABLE,
00483               NULL, NULL,
00484               NULL, NULL, NULL, NULL, NULL,
00485               offsetof(struct slap_internal_schema, si_ad_creatorsName) },
00486        { "modifiersName", "( 2.5.18.4 NAME 'modifiersName' "
00487                      "DESC 'RFC4512: name of last modifier' "
00488                      "EQUALITY distinguishedNameMatch "
00489                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
00490                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00491               NULL, SLAP_AT_MANAGEABLE,
00492               NULL, NULL,
00493               NULL, NULL, NULL, NULL, NULL,
00494               offsetof(struct slap_internal_schema, si_ad_modifiersName) },
00495        { "hasSubordinates", "( 2.5.18.9 NAME 'hasSubordinates' "
00496                      "DESC 'X.501: entry has children' "
00497                      "EQUALITY booleanMatch "
00498                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
00499                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00500               NULL, SLAP_AT_DYNAMIC,
00501               NULL, NULL,
00502               NULL, NULL, NULL, NULL, NULL,
00503               offsetof(struct slap_internal_schema, si_ad_hasSubordinates) },
00504        { "subschemaSubentry", "( 2.5.18.10 NAME 'subschemaSubentry' "
00505                      "DESC 'RFC4512: name of controlling subschema entry' "
00506                      "EQUALITY distinguishedNameMatch "
00507                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE "
00508                      "NO-USER-MODIFICATION USAGE directoryOperation )",
00509               NULL, SLAP_AT_DYNAMIC,
00510               NULL, NULL,
00511               NULL, NULL, NULL, NULL, NULL,
00512               offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
00513 #ifdef LDAP_COLLECTIVE_ATTRIBUTES
00514        { "collectiveAttributeSubentries", "( 2.5.18.12 "
00515                      "NAME 'collectiveAttributeSubentries' "
00516                      "DESC 'RFC3671: collective attribute subentries' "
00517                      "EQUALITY distinguishedNameMatch "
00518                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
00519                      "NO-USER-MODIFICATION USAGE directoryOperation )",
00520               NULL, SLAP_AT_HIDE,
00521               NULL, NULL,
00522               NULL, NULL, NULL, NULL, NULL,
00523               offsetof(struct slap_internal_schema, si_ad_collectiveSubentries) },
00524        { "collectiveExclusions", "( 2.5.18.7 NAME 'collectiveExclusions' "
00525                      "DESC 'RFC3671: collective attribute exclusions' "
00526                      "EQUALITY objectIdentifierMatch "
00527                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
00528                      "USAGE directoryOperation )",
00529               NULL, SLAP_AT_HIDE,
00530               NULL, NULL,
00531               NULL, NULL, NULL, NULL, NULL,
00532               offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) },
00533 #endif
00534 
00535        { "entryDN", "( 1.3.6.1.1.20 NAME 'entryDN' "   
00536                      "DESC 'DN of the entry' "
00537                      "EQUALITY distinguishedNameMatch "
00538                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
00539                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00540               NULL, SLAP_AT_DYNAMIC,
00541               NULL, NULL,
00542               NULL, NULL, NULL, NULL, NULL,
00543               offsetof(struct slap_internal_schema, si_ad_entryDN) },
00544        { "entryUUID", "( 1.3.6.1.1.16.4 NAME 'entryUUID' "   
00545                      "DESC 'UUID of the entry' "
00546                      "EQUALITY UUIDMatch "
00547                      "ORDERING UUIDOrderingMatch "
00548                      "SYNTAX 1.3.6.1.1.16.1 "
00549                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00550               NULL, SLAP_AT_MANAGEABLE,
00551               NULL, NULL,
00552               NULL, NULL, NULL, NULL, NULL,
00553               offsetof(struct slap_internal_schema, si_ad_entryUUID) },
00554        { "entryCSN", "( 1.3.6.1.4.1.4203.666.1.7 NAME 'entryCSN' "
00555                      "DESC 'change sequence number of the entry content' "
00556                      "EQUALITY CSNMatch "
00557                      "ORDERING CSNOrderingMatch "
00558                      "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} "
00559                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00560               NULL, SLAP_AT_HIDE,
00561               NULL, NULL,
00562               NULL, NULL, NULL, NULL, NULL,
00563               offsetof(struct slap_internal_schema, si_ad_entryCSN) },
00564        { "namingCSN", "( 1.3.6.1.4.1.4203.666.1.13 NAME 'namingCSN' "
00565                      "DESC 'change sequence number of the entry naming (RDN)' "
00566                      "EQUALITY CSNMatch "
00567                      "ORDERING CSNOrderingMatch "
00568                      "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} "
00569                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00570               NULL, SLAP_AT_HIDE,
00571               NULL, NULL,
00572               NULL, NULL, NULL, NULL, NULL,
00573               offsetof(struct slap_internal_schema, si_ad_namingCSN) },
00574 
00575 #ifdef LDAP_SUPERIOR_UUID
00576        { "superiorUUID", "( 1.3.6.1.4.1.4203.666.1.11 NAME 'superiorUUID' "   
00577                      "DESC 'UUID of the superior entry' "
00578                      "EQUALITY UUIDMatch "
00579                      "ORDERING UUIDOrderingMatch "
00580                      "SYNTAX 1.3.6.1.1.16.1 "
00581                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
00582               NULL, SLAP_AT_HIDE,
00583               NULL, NULL,
00584               NULL, NULL, NULL, NULL, NULL,
00585               offsetof(struct slap_internal_schema, si_ad_superiorUUID) },
00586 #endif
00587 
00588        { "syncreplCookie", "( 1.3.6.1.4.1.4203.666.1.23 "
00589                      "NAME 'syncreplCookie' "
00590                      "DESC 'syncrepl Cookie for shadow copy' "
00591                      "EQUALITY octetStringMatch "
00592                      "ORDERING octetStringOrderingMatch "
00593                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "
00594                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
00595               NULL, SLAP_AT_HIDE,
00596               NULL, NULL,
00597               NULL, NULL, NULL, NULL, NULL,
00598               offsetof(struct slap_internal_schema, si_ad_syncreplCookie) },
00599 
00600        { "contextCSN", "( 1.3.6.1.4.1.4203.666.1.25 "
00601                      "NAME 'contextCSN' "
00602                      "DESC 'the largest committed CSN of a context' "
00603                      "EQUALITY CSNMatch "
00604                      "ORDERING CSNOrderingMatch "
00605                      "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} "
00606                      "NO-USER-MODIFICATION USAGE dSAOperation )",
00607               NULL, SLAP_AT_HIDE,
00608               NULL, NULL,
00609               NULL, NULL, NULL, NULL, NULL,
00610               offsetof(struct slap_internal_schema, si_ad_contextCSN) },
00611 
00612 #ifdef LDAP_SYNC_TIMESTAMP
00613        { "syncTimestamp", "( 1.3.6.1.4.1.4203.666.1.26 NAME 'syncTimestamp' "
00614                      "DESC 'Time which object was replicated' "
00615                      "EQUALITY generalizedTimeMatch "
00616                      "ORDERING generalizedTimeOrderingMatch "
00617                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
00618                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
00619               NULL, 0,
00620               NULL, NULL,
00621               NULL, NULL, NULL, NULL, NULL,
00622               offsetof(struct slap_internal_schema, si_ad_syncTimestamp) },
00623 #endif
00624 
00625        /* root DSE attributes */
00626        { "altServer", "( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' "
00627                      "DESC 'RFC4512: alternative servers' "
00628                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation )",
00629               rootDseAttribute, 0,
00630               NULL, NULL,
00631               NULL, NULL, NULL, NULL, NULL,
00632               offsetof(struct slap_internal_schema, si_ad_altServer) },
00633        { "namingContexts", "( 1.3.6.1.4.1.1466.101.120.5 "
00634                      "NAME 'namingContexts' "
00635                      "DESC 'RFC4512: naming contexts' "
00636                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation )",
00637               rootDseAttribute, 0,
00638               NULL, NULL,
00639               NULL, NULL, NULL, NULL, NULL,
00640               offsetof(struct slap_internal_schema, si_ad_namingContexts) },
00641        { "supportedControl", "( 1.3.6.1.4.1.1466.101.120.13 "
00642                      "NAME 'supportedControl' "
00643                      "DESC 'RFC4512: supported controls' "
00644                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
00645               rootDseAttribute, 0,
00646               NULL, NULL,
00647               NULL, NULL, NULL, NULL, NULL,
00648               offsetof(struct slap_internal_schema, si_ad_supportedControl) },
00649        { "supportedExtension", "( 1.3.6.1.4.1.1466.101.120.7 "
00650                      "NAME 'supportedExtension' "
00651                      "DESC 'RFC4512: supported extended operations' "
00652                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )",
00653               rootDseAttribute, 0,
00654               NULL, NULL,
00655               NULL, NULL, NULL, NULL, NULL,
00656               offsetof(struct slap_internal_schema, si_ad_supportedExtension) },
00657        { "supportedLDAPVersion", "( 1.3.6.1.4.1.1466.101.120.15 "
00658                      "NAME 'supportedLDAPVersion' "
00659                      "DESC 'RFC4512: supported LDAP versions' "
00660                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation )",
00661               rootDseAttribute, 0,
00662               NULL, NULL,
00663               NULL, NULL, NULL, NULL, NULL,
00664               offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) },
00665        { "supportedSASLMechanisms", "( 1.3.6.1.4.1.1466.101.120.14 "
00666                      "NAME 'supportedSASLMechanisms' "
00667                      "DESC 'RFC4512: supported SASL mechanisms'"
00668                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )",
00669               rootDseAttribute, 0,
00670               NULL, NULL,
00671               NULL, NULL, NULL, NULL, NULL,
00672               offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) },
00673        { "supportedFeatures", "( 1.3.6.1.4.1.4203.1.3.5 "
00674                      "NAME 'supportedFeatures' "
00675                      "DESC 'RFC4512: features supported by the server' "
00676                      "EQUALITY objectIdentifierMatch "
00677                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
00678                      "USAGE dSAOperation )",
00679               rootDseAttribute, 0,
00680               NULL, NULL,
00681               NULL, NULL, NULL, NULL, NULL,
00682               offsetof(struct slap_internal_schema, si_ad_supportedFeatures) },
00683        { "monitorContext", "( 1.3.6.1.4.1.4203.666.1.10 "
00684                      "NAME 'monitorContext' "
00685                      "DESC 'monitor context' "
00686                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
00687                      "EQUALITY distinguishedNameMatch "
00688                      "SINGLE-VALUE NO-USER-MODIFICATION "
00689                      "USAGE dSAOperation )",
00690               rootDseAttribute, SLAP_AT_HIDE,
00691               NULL, NULL,
00692               NULL, NULL, NULL, NULL, NULL,
00693               offsetof(struct slap_internal_schema, si_ad_monitorContext) },
00694        { "configContext", "( 1.3.6.1.4.1.4203.1.12.2.1 "
00695                      "NAME 'configContext' "
00696                      "DESC 'config context' "
00697                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
00698                      "EQUALITY distinguishedNameMatch "
00699                      "SINGLE-VALUE NO-USER-MODIFICATION "
00700                      "USAGE dSAOperation )",
00701               rootDseAttribute, SLAP_AT_HIDE,
00702               NULL, NULL,
00703               NULL, NULL, NULL, NULL, NULL,
00704               offsetof(struct slap_internal_schema, si_ad_configContext) },
00705        { "vendorName", "( 1.3.6.1.1.4 NAME 'vendorName' "
00706                      "DESC 'RFC3045: name of implementation vendor' "
00707                      "EQUALITY caseExactMatch "
00708                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
00709                      "SINGLE-VALUE NO-USER-MODIFICATION "
00710                      "USAGE dSAOperation )",
00711               rootDseAttribute, 0,
00712               NULL, NULL,
00713               NULL, NULL, NULL, NULL, NULL,
00714               offsetof(struct slap_internal_schema, si_ad_vendorName) },
00715        { "vendorVersion", "( 1.3.6.1.1.5 NAME 'vendorVersion' "
00716                      "DESC 'RFC3045: version of implementation' "
00717                      "EQUALITY caseExactMatch "
00718                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
00719                      "SINGLE-VALUE NO-USER-MODIFICATION "
00720                      "USAGE dSAOperation )",
00721               rootDseAttribute, 0,
00722               NULL, NULL,
00723               NULL, NULL, NULL, NULL, NULL,
00724               offsetof(struct slap_internal_schema, si_ad_vendorVersion) },
00725 
00726        /* subentry attributes */
00727        { "administrativeRole", "( 2.5.18.5 NAME 'administrativeRole' "
00728                      "DESC 'RFC3672: administrative role' "
00729                      "EQUALITY objectIdentifierMatch "
00730                      "USAGE directoryOperation "
00731                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
00732               administrativeRoleAttribute, SLAP_AT_HIDE,
00733               NULL, NULL,
00734               NULL, NULL, NULL, NULL, NULL,
00735               offsetof(struct slap_internal_schema, si_ad_administrativeRole) },
00736        { "subtreeSpecification", "( 2.5.18.6 NAME 'subtreeSpecification' "
00737                      "DESC 'RFC3672: subtree specification' "
00738                      "SINGLE-VALUE "
00739                      "USAGE directoryOperation "
00740                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.45 )",
00741               subentryAttribute, SLAP_AT_HIDE,
00742               NULL, NULL,
00743               NULL, NULL, NULL, NULL, NULL,
00744               offsetof(struct slap_internal_schema, si_ad_subtreeSpecification) },
00745 
00746        /* subschema subentry attributes */
00747        { "dITStructureRules", "( 2.5.21.1 NAME 'dITStructureRules' "
00748                      "DESC 'RFC4512: DIT structure rules' "
00749                      "EQUALITY integerFirstComponentMatch "
00750                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 "
00751                      "USAGE directoryOperation ) ",
00752               subentryAttribute, SLAP_AT_HIDE,
00753               NULL, NULL,
00754               NULL, NULL, NULL, NULL, NULL,
00755               offsetof(struct slap_internal_schema, si_ad_ditStructureRules) },
00756        { "dITContentRules", "( 2.5.21.2 NAME 'dITContentRules' "
00757                      "DESC 'RFC4512: DIT content rules' "
00758                      "EQUALITY objectIdentifierFirstComponentMatch "
00759                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )",
00760               subentryAttribute, SLAP_AT_HIDE,
00761               oidValidate, NULL,
00762               NULL, NULL, objectClassMatch, NULL, NULL,
00763               offsetof(struct slap_internal_schema, si_ad_ditContentRules) },
00764        { "matchingRules", "( 2.5.21.4 NAME 'matchingRules' "
00765                      "DESC 'RFC4512: matching rules' "
00766                      "EQUALITY objectIdentifierFirstComponentMatch "
00767                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )",
00768               subentryAttribute, 0,
00769               oidValidate, NULL,
00770               NULL, NULL, matchingRuleMatch, NULL, NULL,
00771               offsetof(struct slap_internal_schema, si_ad_matchingRules) },
00772        { "attributeTypes", "( 2.5.21.5 NAME 'attributeTypes' "
00773                      "DESC 'RFC4512: attribute types' "
00774                      "EQUALITY objectIdentifierFirstComponentMatch "
00775                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )",
00776               subentryAttribute, 0,
00777               oidValidate, NULL,
00778               NULL, NULL, attributeTypeMatch, NULL, NULL,
00779               offsetof(struct slap_internal_schema, si_ad_attributeTypes) },
00780        { "objectClasses", "( 2.5.21.6 NAME 'objectClasses' "
00781                      "DESC 'RFC4512: object classes' "
00782                      "EQUALITY objectIdentifierFirstComponentMatch "
00783                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )",
00784               subentryAttribute, 0,
00785               oidValidate, NULL,
00786               NULL, NULL, objectClassMatch, NULL, NULL,
00787               offsetof(struct slap_internal_schema, si_ad_objectClasses) },
00788        { "nameForms", "( 2.5.21.7 NAME 'nameForms' "
00789                      "DESC 'RFC4512: name forms ' "
00790                      "EQUALITY objectIdentifierFirstComponentMatch "
00791                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation )",
00792               subentryAttribute, SLAP_AT_HIDE,
00793               NULL, NULL,
00794               NULL, NULL, NULL, NULL, NULL,
00795               offsetof(struct slap_internal_schema, si_ad_nameForms) },
00796        { "matchingRuleUse", "( 2.5.21.8 NAME 'matchingRuleUse' "
00797                      "DESC 'RFC4512: matching rule uses' "
00798                      "EQUALITY objectIdentifierFirstComponentMatch "
00799                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )",
00800               subentryAttribute, 0,
00801               oidValidate, NULL,
00802               NULL, NULL, matchingRuleMatch, NULL, NULL,
00803               offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) },
00804 
00805        { "ldapSyntaxes", "( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' "
00806                      "DESC 'RFC4512: LDAP syntaxes' "
00807                      "EQUALITY objectIdentifierFirstComponentMatch "
00808                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation )",
00809               subentryAttribute, 0,
00810               NULL, NULL,
00811               NULL, NULL, NULL, NULL, NULL,
00812               offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) },
00813 
00814        /* knowledge information */
00815        { "aliasedObjectName", "( 2.5.4.1 "
00816                      "NAME ( 'aliasedObjectName' 'aliasedEntryName' ) "
00817                      "DESC 'RFC4512: name of aliased object' "
00818                      "EQUALITY distinguishedNameMatch "
00819                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )",
00820               aliasAttribute, SLAP_AT_FINAL,
00821               NULL, NULL,
00822               NULL, NULL, NULL, NULL, NULL,
00823               offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) },
00824        { "ref", "( 2.16.840.1.113730.3.1.34 NAME 'ref' "
00825                      "DESC 'RFC3296: subordinate referral URL' "
00826                      "EQUALITY caseExactMatch "
00827                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
00828                      "USAGE distributedOperation )",
00829               referralAttribute, 0,
00830               NULL, NULL,
00831               NULL, NULL, NULL, NULL, NULL,
00832               offsetof(struct slap_internal_schema, si_ad_ref) },
00833 
00834        /* access control internals */
00835        { "entry", "( 1.3.6.1.4.1.4203.1.3.1 "
00836                      "NAME 'entry' "
00837                      "DESC 'OpenLDAP ACL entry pseudo-attribute' "
00838                      "SYNTAX 1.3.6.1.4.1.4203.1.1.1 "
00839                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
00840               NULL, SLAP_AT_HIDE,
00841               NULL, NULL,
00842               NULL, NULL, NULL, NULL, NULL,
00843               offsetof(struct slap_internal_schema, si_ad_entry) },
00844        { "children", "( 1.3.6.1.4.1.4203.1.3.2 "
00845                      "NAME 'children' "
00846                      "DESC 'OpenLDAP ACL children pseudo-attribute' "
00847                      "SYNTAX 1.3.6.1.4.1.4203.1.1.1 "
00848                      "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )",
00849               NULL, SLAP_AT_HIDE,
00850               NULL, NULL,
00851               NULL, NULL, NULL, NULL, NULL,
00852               offsetof(struct slap_internal_schema, si_ad_children) },
00853 
00854        /* access control externals */
00855        { "authzTo", "( 1.3.6.1.4.1.4203.666.1.8 "
00856                      "NAME ( 'authzTo' 'saslAuthzTo' ) "
00857                      "DESC 'proxy authorization targets' "
00858                      "EQUALITY authzMatch "
00859                      "SYNTAX 1.3.6.1.4.1.4203.666.2.7 "
00860                      "X-ORDERED 'VALUES' "
00861                      "USAGE distributedOperation )",
00862               NULL, SLAP_AT_HIDE,
00863               NULL, NULL,
00864               NULL, NULL, NULL, NULL, NULL,
00865               offsetof(struct slap_internal_schema, si_ad_saslAuthzTo) },
00866        { "authzFrom", "( 1.3.6.1.4.1.4203.666.1.9 "
00867                      "NAME ( 'authzFrom' 'saslAuthzFrom' ) "
00868                      "DESC 'proxy authorization sources' "
00869                      "EQUALITY authzMatch "
00870                      "SYNTAX 1.3.6.1.4.1.4203.666.2.7 "
00871                      "X-ORDERED 'VALUES' "
00872                      "USAGE distributedOperation )",
00873               NULL, SLAP_AT_HIDE,
00874               NULL, NULL,
00875               NULL, NULL, NULL, NULL, NULL,
00876               offsetof(struct slap_internal_schema, si_ad_saslAuthzFrom) },
00877 
00878 #ifdef LDAP_DYNAMIC_OBJECTS
00879        { "entryTtl", "( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' "
00880                      "DESC 'RFC2589: entry time-to-live' "
00881                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE "
00882                      "NO-USER-MODIFICATION USAGE dSAOperation )",
00883               dynamicAttribute, SLAP_AT_MANAGEABLE,
00884               NULL, NULL,
00885               NULL, NULL, NULL, NULL, NULL,
00886               offsetof(struct slap_internal_schema, si_ad_entryTtl) },
00887        { "dynamicSubtrees", "( 1.3.6.1.4.1.1466.101.119.4 "
00888                      "NAME 'dynamicSubtrees' "
00889                      "DESC 'RFC2589: dynamic subtrees' "
00890                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION "
00891                      "USAGE dSAOperation )",
00892               rootDseAttribute, 0,
00893               NULL, NULL,
00894               NULL, NULL, NULL, NULL, NULL,
00895               offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },
00896 #endif
00897 
00898        /* userApplication attributes (which system schema depends upon) */
00899        { "distinguishedName", "( 2.5.4.49 NAME 'distinguishedName' "
00900                      "DESC 'RFC4519: common supertype of DN attributes' "
00901                      "EQUALITY distinguishedNameMatch "
00902                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
00903               NULL, SLAP_AT_ABSTRACT,
00904               NULL, NULL,
00905               NULL, NULL, NULL, NULL, NULL,
00906               offsetof(struct slap_internal_schema, si_ad_distinguishedName) },
00907        { "name", "( 2.5.4.41 NAME 'name' "
00908                      "DESC 'RFC4519: common supertype of name attributes' "
00909                      "EQUALITY caseIgnoreMatch "
00910                      "SUBSTR caseIgnoreSubstringsMatch "
00911                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )",
00912               NULL, SLAP_AT_ABSTRACT,
00913               NULL, NULL,
00914               NULL, NULL, NULL, NULL, NULL,
00915               offsetof(struct slap_internal_schema, si_ad_name) },
00916        { "cn", "( 2.5.4.3 NAME ( 'cn' 'commonName' ) "
00917                      "DESC 'RFC4519: common name(s) for which the entity is known by' "
00918                      "SUP name )",
00919               NULL, 0,
00920               NULL, NULL,
00921               NULL, NULL, NULL, NULL, NULL,
00922               offsetof(struct slap_internal_schema, si_ad_cn) },
00923        { "uid", "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) "
00924                      "DESC 'RFC4519: user identifier' "
00925                      "EQUALITY caseIgnoreMatch "
00926                      "SUBSTR caseIgnoreSubstringsMatch "
00927                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )",
00928               NULL, 0,
00929               NULL, NULL,
00930               NULL, NULL, NULL, NULL, NULL,
00931               offsetof(struct slap_internal_schema, si_ad_uid) },
00932        { "uidNumber", /* for ldapi:// */
00933               "( 1.3.6.1.1.1.1.0 NAME 'uidNumber' "
00934               "DESC 'RFC2307: An integer uniquely identifying a user "
00935                             "in an administrative domain' "
00936               "EQUALITY integerMatch "
00937               "ORDERING integerOrderingMatch "
00938               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
00939               NULL, 0,
00940               NULL, NULL,
00941               NULL, NULL, NULL, NULL, NULL,
00942               offsetof(struct slap_internal_schema, si_ad_uidNumber) },
00943        { "gidNumber", /* for ldapi:// */
00944               "( 1.3.6.1.1.1.1.1 NAME 'gidNumber' "
00945               "DESC 'RFC2307: An integer uniquely identifying a group "
00946                             "in an administrative domain' "
00947               "EQUALITY integerMatch "
00948               "ORDERING integerOrderingMatch "
00949               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
00950               NULL, 0,
00951               NULL, NULL,
00952               NULL, NULL, NULL, NULL, NULL,
00953               offsetof(struct slap_internal_schema, si_ad_gidNumber) },
00954        { "userPassword", "( 2.5.4.35 NAME 'userPassword' "
00955                      "DESC 'RFC4519/2307: password of user' "
00956                      "EQUALITY octetStringMatch "
00957                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )",
00958               NULL, 0,
00959               NULL, NULL,
00960               NULL, NULL, NULL, NULL, NULL,
00961               offsetof(struct slap_internal_schema, si_ad_userPassword) },
00962 
00963        { "labeledURI", "( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI' "
00964                      "DESC 'RFC2079: Uniform Resource Identifier with optional label' "
00965                      "EQUALITY caseExactMatch "
00966                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
00967               NULL, 0,
00968               NULL, NULL,
00969               NULL, NULL, NULL, NULL, NULL,
00970               offsetof(struct slap_internal_schema, si_ad_labeledURI) },
00971 
00972 #ifdef SLAPD_AUTHPASSWD
00973        { "authPassword", "( 1.3.6.1.4.1.4203.1.3.4 "
00974                      "NAME 'authPassword' "
00975                      "DESC 'RFC3112: authentication password attribute' "
00976                      "EQUALITY 1.3.6.1.4.1.4203.1.2.2 "
00977                      "SYNTAX 1.3.6.1.4.1.4203.1.1.2 )",
00978               NULL, 0,
00979               NULL, NULL,
00980               NULL, NULL, NULL, NULL, NULL,
00981               offsetof(struct slap_internal_schema, si_ad_authPassword) },
00982        { "supportedAuthPasswordSchemes", "( 1.3.6.1.4.1.4203.1.3.3 "
00983                      "NAME 'supportedAuthPasswordSchemes' "
00984                      "DESC 'RFC3112: supported authPassword schemes' "
00985                      "EQUALITY caseExactIA5Match "
00986                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} "
00987                      "USAGE dSAOperation )",
00988               subschemaAttribute, 0,
00989               NULL, NULL,
00990               NULL, NULL, NULL, NULL, NULL,
00991               offsetof(struct slap_internal_schema, si_ad_authPasswordSchemes) },
00992 #endif
00993 
00994        { "description", "( 2.5.4.13 NAME 'description' "
00995                      "DESC 'RFC4519: descriptive information' "
00996                      "EQUALITY caseIgnoreMatch "
00997                      "SUBSTR caseIgnoreSubstringsMatch "
00998                      "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )",
00999               NULL, 0,
01000               NULL, NULL,
01001               NULL, NULL, NULL, NULL, NULL,
01002               offsetof(struct slap_internal_schema, si_ad_description) },
01003 
01004        { "seeAlso", "( 2.5.4.34 NAME 'seeAlso' "
01005                      "DESC 'RFC4519: DN of related object' "
01006                      "SUP distinguishedName )",
01007               NULL, 0,
01008               NULL, NULL,
01009               NULL, NULL, NULL, NULL, NULL,
01010               offsetof(struct slap_internal_schema, si_ad_seeAlso) },
01011 
01012        { NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 }
01013 };
01014 
01015 static AttributeType slap_at_undefined = {
01016        { "1.1.1", NULL, "Catchall for undefined attribute types", 1, NULL,
01017               NULL, NULL, NULL, NULL,
01018               0, 0, 0, 1, LDAP_SCHEMA_DSA_OPERATION, NULL }, /* LDAPAttributeType */
01019        BER_BVC("UNDEFINED"), /* cname */
01020        NULL, /* sup */
01021        NULL, /* subtypes */
01022        NULL, NULL, NULL, NULL,     /* matching rules routines */
01023        NULL, /* syntax (will be set later to "octetString") */
01024        NULL, /* schema check function */
01025        NULL, /* oidmacro */
01026        NULL, /* soidmacro */
01027        SLAP_AT_ABSTRACT|SLAP_AT_FINAL,    /* mask */
01028        { NULL }, /* next */
01029        NULL /* attribute description */
01030        /* mutex (don't know how to initialize it :) */
01031 };
01032 
01033 static AttributeType slap_at_proxied = {
01034        { "1.1.1", NULL, "Catchall for undefined proxied attribute types", 1, NULL,
01035               NULL, NULL, NULL, NULL,
01036               0, 0, 0, 0, LDAP_SCHEMA_USER_APPLICATIONS, NULL }, /* LDAPAttributeType */
01037        BER_BVC("PROXIED"), /* cname */
01038        NULL, /* sup */
01039        NULL, /* subtypes */
01040        NULL, NULL, NULL, NULL,     /* matching rules routines (will be set later) */
01041        NULL, /* syntax (will be set later to "octetString") */
01042        NULL, /* schema check function */
01043        NULL, /* oidmacro */
01044        NULL, /* soidmacro */
01045        SLAP_AT_ABSTRACT|SLAP_AT_FINAL,    /* mask */
01046        { NULL }, /* next */
01047        NULL /* attribute description */
01048        /* mutex (don't know how to initialize it :) */
01049 };
01050 
01051 static struct slap_schema_mr_map {
01052        char *ssmm_name;
01053        size_t ssmm_offset;
01054 } mr_map[] = {
01055        { "caseExactIA5Match",
01056               offsetof(struct slap_internal_schema, si_mr_caseExactIA5Match) },
01057        { "caseExactMatch",
01058               offsetof(struct slap_internal_schema, si_mr_caseExactMatch) },
01059        { "caseExactSubstringsMatch",
01060               offsetof(struct slap_internal_schema, si_mr_caseExactSubstringsMatch) },
01061        { "distinguishedNameMatch",
01062               offsetof(struct slap_internal_schema, si_mr_distinguishedNameMatch) },
01063        { "dnSubtreeMatch",
01064               offsetof(struct slap_internal_schema, si_mr_dnSubtreeMatch) },
01065        { "dnOneLevelMatch",
01066               offsetof(struct slap_internal_schema, si_mr_dnOneLevelMatch) },
01067        { "dnSubordinateMatch",
01068               offsetof(struct slap_internal_schema, si_mr_dnSubordinateMatch) },
01069        { "dnSuperiorMatch",
01070               offsetof(struct slap_internal_schema, si_mr_dnSuperiorMatch) },
01071        { "integerMatch",
01072               offsetof(struct slap_internal_schema, si_mr_integerMatch) },
01073        { "integerFirstComponentMatch",
01074               offsetof(struct slap_internal_schema,
01075                      si_mr_integerFirstComponentMatch) },
01076        { "objectIdentifierFirstComponentMatch",
01077               offsetof(struct slap_internal_schema,
01078                      si_mr_objectIdentifierFirstComponentMatch) },
01079        { "caseIgnoreMatch",
01080               offsetof(struct slap_internal_schema, si_mr_caseIgnoreMatch) },
01081        { "caseIgnoreListMatch",
01082               offsetof(struct slap_internal_schema, si_mr_caseIgnoreListMatch) },
01083        { NULL, 0 }
01084 };
01085 
01086 static struct slap_schema_syn_map {
01087        char *sssm_name;
01088        size_t sssm_offset;
01089 } syn_map[] = {
01090        { "1.3.6.1.4.1.1466.115.121.1.15",
01091               offsetof(struct slap_internal_schema, si_syn_directoryString) },
01092        { "1.3.6.1.4.1.1466.115.121.1.12",
01093               offsetof(struct slap_internal_schema, si_syn_distinguishedName) },
01094        { "1.3.6.1.4.1.1466.115.121.1.27",
01095               offsetof(struct slap_internal_schema, si_syn_integer) },
01096        { "1.3.6.1.4.1.1466.115.121.1.40",
01097               offsetof(struct slap_internal_schema, si_syn_octetString) },
01098        { "1.3.6.1.4.1.1466.115.121.1.3",
01099               offsetof(struct slap_internal_schema, si_syn_attributeTypeDesc) },
01100        { "1.3.6.1.4.1.1466.115.121.1.16",
01101               offsetof(struct slap_internal_schema, si_syn_ditContentRuleDesc) },
01102        { "1.3.6.1.4.1.1466.115.121.1.54",
01103               offsetof(struct slap_internal_schema, si_syn_ldapSyntaxDesc) },
01104        { "1.3.6.1.4.1.1466.115.121.1.30",
01105               offsetof(struct slap_internal_schema, si_syn_matchingRuleDesc) },
01106        { "1.3.6.1.4.1.1466.115.121.1.31",
01107               offsetof(struct slap_internal_schema, si_syn_matchingRuleUseDesc) },
01108        { "1.3.6.1.4.1.1466.115.121.1.35",
01109               offsetof(struct slap_internal_schema, si_syn_nameFormDesc) },
01110        { "1.3.6.1.4.1.1466.115.121.1.37",
01111               offsetof(struct slap_internal_schema, si_syn_objectClassDesc) },
01112        { "1.3.6.1.4.1.1466.115.121.1.17",
01113               offsetof(struct slap_internal_schema, si_syn_ditStructureRuleDesc) },
01114        { NULL, 0 }
01115 };
01116 
01117 int
01118 slap_schema_load( void )
01119 {
01120        int i;
01121 
01122        for( i=0; syn_map[i].sssm_name; i++ ) {
01123               Syntax ** synp = (Syntax **)
01124                      &(((char *) &slap_schema)[syn_map[i].sssm_offset]);
01125 
01126               assert( *synp == NULL );
01127 
01128               *synp = syn_find( syn_map[i].sssm_name );
01129 
01130               if( *synp == NULL ) {
01131                      fprintf( stderr, "slap_schema_load: Syntax: "
01132                             "No syntax \"%s\" defined in schema\n",
01133                             syn_map[i].sssm_name );
01134                      return LDAP_INVALID_SYNTAX;
01135               }
01136        }
01137 
01138        for( i=0; mr_map[i].ssmm_name; i++ ) {
01139               MatchingRule ** mrp = (MatchingRule **)
01140                      &(((char *) &slap_schema)[mr_map[i].ssmm_offset]);
01141 
01142               assert( *mrp == NULL );
01143 
01144               *mrp = mr_find( mr_map[i].ssmm_name );
01145 
01146               if( *mrp == NULL ) {
01147                      fprintf( stderr, "slap_schema_load: MatchingRule: "
01148                             "No matching rule \"%s\" defined in schema\n",
01149                             mr_map[i].ssmm_name );
01150                      return LDAP_INAPPROPRIATE_MATCHING;
01151               }
01152        }
01153 
01154        slap_at_undefined.sat_syntax = slap_schema.si_syn_octetString;
01155        slap_schema.si_at_undefined = &slap_at_undefined;
01156 
01157        slap_at_proxied.sat_equality = mr_find( "octetStringMatch" );
01158        slap_at_proxied.sat_approx = mr_find( "octetStringMatch" );
01159        slap_at_proxied.sat_ordering = mr_find( "octetStringOrderingMatch" );
01160        slap_at_proxied.sat_substr = mr_find( "octetStringSubstringsMatch" );
01161        slap_at_proxied.sat_syntax = slap_schema.si_syn_octetString;
01162        slap_schema.si_at_proxied = &slap_at_proxied;
01163 
01164        ldap_pvt_thread_mutex_init( &ad_index_mutex );
01165        ldap_pvt_thread_mutex_init( &ad_undef_mutex );
01166        ldap_pvt_thread_mutex_init( &oc_undef_mutex );
01167 
01168        for( i=0; ad_map[i].ssam_name; i++ ) {
01169               assert( ad_map[i].ssam_defn != NULL );
01170               {
01171                      LDAPAttributeType *at;
01172                      int           code;
01173                      const char    *err;
01174 
01175                      at = ldap_str2attributetype( ad_map[i].ssam_defn,
01176                             &code, &err, LDAP_SCHEMA_ALLOW_ALL );
01177                      if ( !at ) {
01178                             fprintf( stderr,
01179                                    "slap_schema_load: AttributeType \"%s\": %s before %s\n",
01180                                     ad_map[i].ssam_name, ldap_scherr2str(code), err );
01181                             return code;
01182                      }
01183 
01184                      if ( at->at_oid == NULL ) {
01185                             fprintf( stderr, "slap_schema_load: "
01186                                    "AttributeType \"%s\": no OID\n",
01187                                    ad_map[i].ssam_name );
01188                             ldap_attributetype_free( at );
01189                             return LDAP_OTHER;
01190                      }
01191 
01192                      code = at_add( at, 0, NULL, NULL, &err );
01193                      if ( code ) {
01194                             ldap_attributetype_free( at );
01195                             fprintf( stderr, "slap_schema_load: AttributeType "
01196                                    "\"%s\": %s: \"%s\"\n",
01197                                     ad_map[i].ssam_name, scherr2str(code), err );
01198                             return code;
01199                      }
01200                      ldap_memfree( at );
01201               }
01202               {
01203                      int rc;
01204                      const char *text;
01205                      Syntax *syntax = NULL;
01206 
01207                      AttributeDescription ** adp = (AttributeDescription **)
01208                             &(((char *) &slap_schema)[ad_map[i].ssam_offset]);
01209 
01210                      assert( *adp == NULL );
01211 
01212                      rc = slap_str2ad( ad_map[i].ssam_name, adp, &text );
01213                      if( rc != LDAP_SUCCESS ) {
01214                             fprintf( stderr, "slap_schema_load: AttributeType \"%s\": "
01215                                    "not defined in schema\n",
01216                                    ad_map[i].ssam_name );
01217                             return rc;
01218                      }
01219 
01220                      if( ad_map[i].ssam_check ) {
01221                             /* install check routine */
01222                             (*adp)->ad_type->sat_check = ad_map[i].ssam_check;
01223                      }
01224                      /* install flags */
01225                      (*adp)->ad_type->sat_flags |= ad_map[i].ssam_flags;
01226 
01227                      /* install custom syntax routines */
01228                      if( ad_map[i].ssam_syn_validate ||
01229                             ad_map[i].ssam_syn_pretty )
01230                      {
01231                             Syntax *syn;
01232 
01233                             syntax = (*adp)->ad_type->sat_syntax;
01234 
01235                             syn = ch_malloc( sizeof( Syntax ) );
01236                             *syn = *syntax;
01237 
01238                             if( ad_map[i].ssam_syn_validate ) {
01239                                    syn->ssyn_validate = ad_map[i].ssam_syn_validate;
01240                             }
01241                             if( ad_map[i].ssam_syn_pretty ) {
01242                                    syn->ssyn_pretty = ad_map[i].ssam_syn_pretty;
01243                             }
01244 
01245                             (*adp)->ad_type->sat_syntax = syn;
01246                      }
01247 
01248                      /* install custom rule routines */
01249                      if( syntax != NULL ||
01250                             ad_map[i].ssam_mr_convert ||
01251                             ad_map[i].ssam_mr_normalize ||
01252                             ad_map[i].ssam_mr_match ||
01253                             ad_map[i].ssam_mr_indexer ||
01254                             ad_map[i].ssam_mr_filter )
01255                      {
01256                             MatchingRule *mr = ch_malloc( sizeof( MatchingRule ) );
01257                             *mr = *(*adp)->ad_type->sat_equality;
01258 
01259                             if ( syntax != NULL ) {
01260                                    mr->smr_syntax = (*adp)->ad_type->sat_syntax;
01261                             }
01262                             if ( ad_map[i].ssam_mr_convert ) {
01263                                    mr->smr_convert = ad_map[i].ssam_mr_convert;
01264                             }
01265                             if ( ad_map[i].ssam_mr_normalize ) {
01266                                    mr->smr_normalize = ad_map[i].ssam_mr_normalize;
01267                             }
01268                             if ( ad_map[i].ssam_mr_match ) {
01269                                    mr->smr_match = ad_map[i].ssam_mr_match;
01270                             }
01271                             if ( ad_map[i].ssam_mr_indexer ) {
01272                                    mr->smr_indexer = ad_map[i].ssam_mr_indexer;
01273                             }
01274                             if ( ad_map[i].ssam_mr_filter ) {
01275                                    mr->smr_filter = ad_map[i].ssam_mr_filter;
01276                             }
01277 
01278                             (*adp)->ad_type->sat_equality = mr;
01279                      }
01280               }
01281        }
01282 
01283        for( i=0; oc_map[i].ssom_name; i++ ) {
01284               assert( oc_map[i].ssom_defn != NULL );
01285               {
01286                      LDAPObjectClass *oc;
01287                      int           code;
01288                      const char    *err;
01289 
01290                      oc = ldap_str2objectclass( oc_map[i].ssom_defn, &code, &err,
01291                             LDAP_SCHEMA_ALLOW_ALL );
01292                      if ( !oc ) {
01293                             fprintf( stderr, "slap_schema_load: ObjectClass "
01294                                    "\"%s\": %s before %s\n",
01295                                    oc_map[i].ssom_name, ldap_scherr2str(code), err );
01296                             return code;
01297                      }
01298 
01299                      if ( oc->oc_oid == NULL ) {
01300                             fprintf( stderr, "slap_schema_load: ObjectClass "
01301                                    "\"%s\": no OID\n",
01302                                    oc_map[i].ssom_name );
01303                             ldap_objectclass_free( oc );
01304                             return LDAP_OTHER;
01305                      }
01306 
01307                      code = oc_add(oc,0,NULL,NULL,&err);
01308                      if ( code ) {
01309                             ldap_objectclass_free( oc );
01310                             fprintf( stderr, "slap_schema_load: ObjectClass "
01311                                    "\"%s\": %s: \"%s\"\n",
01312                                    oc_map[i].ssom_name, scherr2str(code), err);
01313                             return code;
01314                      }
01315                      ldap_memfree(oc);
01316 
01317               }
01318               {
01319                      ObjectClass ** ocp = (ObjectClass **)
01320                             &(((char *) &slap_schema)[oc_map[i].ssom_offset]);
01321 
01322                      assert( *ocp == NULL );
01323 
01324                      *ocp = oc_find( oc_map[i].ssom_name );
01325                      if( *ocp == NULL ) {
01326                             fprintf( stderr, "slap_schema_load: "
01327                                    "ObjectClass \"%s\": not defined in schema\n",
01328                                    oc_map[i].ssom_name );
01329                             return LDAP_OBJECT_CLASS_VIOLATION;
01330                      }
01331 
01332                      if( oc_map[i].ssom_check ) {
01333                             /* install check routine */
01334                             (*ocp)->soc_check = oc_map[i].ssom_check;
01335                      }
01336                      /* install flags */
01337                      (*ocp)->soc_flags |= oc_map[i].ssom_flags;
01338               }
01339        }
01340 
01341        return LDAP_SUCCESS;
01342 }
01343 
01344 int
01345 slap_schema_check( void )
01346 {
01347        /* we should only be called once after schema_init() was called */
01348        assert( schema_init_done == 1 );
01349 
01350        /*
01351         * cycle thru attributeTypes to build matchingRuleUse
01352         */
01353        if ( matching_rule_use_init() ) {
01354               return LDAP_OTHER;
01355        }
01356 
01357        ++schema_init_done;
01358        return LDAP_SUCCESS;
01359 }
01360 
01361 static int rootDseObjectClass (
01362        Backend *be,
01363        Entry *e,
01364        ObjectClass *oc,
01365        const char** text,
01366        char *textbuf, size_t textlen )
01367 {
01368        *text = textbuf;
01369 
01370        if( e->e_nname.bv_len ) {
01371               snprintf( textbuf, textlen,
01372                      "objectClass \"%s\" only allowed in the root DSE",
01373                      oc->soc_oid );
01374               return LDAP_OBJECT_CLASS_VIOLATION;
01375        }
01376 
01377        /* we should not be called for the root DSE */
01378        assert( 0 );
01379        return LDAP_SUCCESS;
01380 }
01381 
01382 static int aliasObjectClass (
01383        Backend *be,
01384        Entry *e,
01385        ObjectClass *oc,
01386        const char** text,
01387        char *textbuf, size_t textlen )
01388 {
01389        *text = textbuf;
01390 
01391        if( !SLAP_ALIASES(be) ) {
01392               snprintf( textbuf, textlen,
01393                      "objectClass \"%s\" not supported in context",
01394                      oc->soc_oid );
01395               return LDAP_OBJECT_CLASS_VIOLATION;
01396        }
01397 
01398        return LDAP_SUCCESS;
01399 }
01400 
01401 static int referralObjectClass (
01402        Backend *be,
01403        Entry *e,
01404        ObjectClass *oc,
01405        const char** text,
01406        char *textbuf, size_t textlen )
01407 {
01408        *text = textbuf;
01409 
01410        if( !SLAP_REFERRALS(be) ) {
01411               snprintf( textbuf, textlen,
01412                      "objectClass \"%s\" not supported in context",
01413                      oc->soc_oid );
01414               return LDAP_OBJECT_CLASS_VIOLATION;
01415        }
01416 
01417        return LDAP_SUCCESS;
01418 }
01419 
01420 static int subentryObjectClass (
01421        Backend *be,
01422        Entry *e,
01423        ObjectClass *oc,
01424        const char** text,
01425        char *textbuf, size_t textlen )
01426 {
01427        *text = textbuf;
01428 
01429        if( !SLAP_SUBENTRIES(be) ) {
01430               snprintf( textbuf, textlen,
01431                      "objectClass \"%s\" not supported in context",
01432                      oc->soc_oid );
01433               return LDAP_OBJECT_CLASS_VIOLATION;
01434        }
01435 
01436        if( oc != slap_schema.si_oc_subentry && !is_entry_subentry( e ) ) {
01437               snprintf( textbuf, textlen,
01438                      "objectClass \"%s\" only allowed in subentries",
01439                      oc->soc_oid );
01440               return LDAP_OBJECT_CLASS_VIOLATION;
01441        }
01442 
01443        return LDAP_SUCCESS;
01444 }
01445 
01446 #ifdef LDAP_DYNAMIC_OBJECTS
01447 static int dynamicObjectClass (
01448        Backend *be,
01449        Entry *e,
01450        ObjectClass *oc,
01451        const char** text,
01452        char *textbuf, size_t textlen )
01453 {
01454        *text = textbuf;
01455 
01456        if( !SLAP_DYNAMIC(be) ) {
01457               snprintf( textbuf, textlen,
01458                      "objectClass \"%s\" not supported in context",
01459                      oc->soc_oid );
01460               return LDAP_OBJECT_CLASS_VIOLATION;
01461        }
01462 
01463        return LDAP_SUCCESS;
01464 }
01465 #endif /* LDAP_DYNAMIC_OBJECTS */
01466 
01467 static int rootDseAttribute (
01468        Backend *be,
01469        Entry *e,
01470        Attribute *attr,
01471        const char** text,
01472        char *textbuf, size_t textlen )
01473 {
01474        *text = textbuf;
01475 
01476        if( e->e_nname.bv_len ) {
01477               snprintf( textbuf, textlen,
01478                      "attribute \"%s\" only allowed in the root DSE",
01479                      attr->a_desc->ad_cname.bv_val );
01480               return LDAP_OBJECT_CLASS_VIOLATION;
01481        }
01482 
01483        /* we should not be called for the root DSE */
01484        assert( 0 );
01485        return LDAP_SUCCESS;
01486 }
01487 
01488 static int aliasAttribute (
01489        Backend *be,
01490        Entry *e,
01491        Attribute *attr,
01492        const char** text,
01493        char *textbuf, size_t textlen )
01494 {
01495        *text = textbuf;
01496 
01497        if( !SLAP_ALIASES(be) ) {
01498               snprintf( textbuf, textlen,
01499                      "attribute \"%s\" not supported in context",
01500                      attr->a_desc->ad_cname.bv_val );
01501               return LDAP_OBJECT_CLASS_VIOLATION;
01502        }
01503 
01504        if( !is_entry_alias( e ) ) {
01505               snprintf( textbuf, textlen,
01506                      "attribute \"%s\" only allowed in the alias",
01507                      attr->a_desc->ad_cname.bv_val );
01508               return LDAP_OBJECT_CLASS_VIOLATION;
01509        }
01510 
01511        return LDAP_SUCCESS;
01512 }
01513 
01514 static int referralAttribute (
01515        Backend *be,
01516        Entry *e,
01517        Attribute *attr,
01518        const char** text,
01519        char *textbuf, size_t textlen )
01520 {
01521        *text = textbuf;
01522 
01523        if( !SLAP_REFERRALS(be) ) {
01524               snprintf( textbuf, textlen,
01525                      "attribute \"%s\" not supported in context",
01526                      attr->a_desc->ad_cname.bv_val );
01527               return LDAP_OBJECT_CLASS_VIOLATION;
01528        }
01529 
01530        if( !is_entry_referral( e ) ) {
01531               snprintf( textbuf, textlen,
01532                      "attribute \"%s\" only allowed in the referral",
01533                      attr->a_desc->ad_cname.bv_val );
01534               return LDAP_OBJECT_CLASS_VIOLATION;
01535        }
01536 
01537        return LDAP_SUCCESS;
01538 }
01539 
01540 static int subentryAttribute (
01541        Backend *be,
01542        Entry *e,
01543        Attribute *attr,
01544        const char** text,
01545        char *textbuf, size_t textlen )
01546 {
01547        *text = textbuf;
01548 
01549        if( !SLAP_SUBENTRIES(be) ) {
01550               snprintf( textbuf, textlen,
01551                      "attribute \"%s\" not supported in context",
01552                      attr->a_desc->ad_cname.bv_val );
01553               return LDAP_OBJECT_CLASS_VIOLATION;
01554        }
01555 
01556        if( !is_entry_subentry( e ) ) {
01557               snprintf( textbuf, textlen,
01558                      "attribute \"%s\" only allowed in the subentry",
01559                      attr->a_desc->ad_cname.bv_val );
01560               return LDAP_OBJECT_CLASS_VIOLATION;
01561        }
01562 
01563        return LDAP_SUCCESS;
01564 }
01565 
01566 static int administrativeRoleAttribute (
01567        Backend *be,
01568        Entry *e,
01569        Attribute *attr,
01570        const char** text,
01571        char *textbuf, size_t textlen )
01572 {
01573        *text = textbuf;
01574 
01575        if( !SLAP_SUBENTRIES(be) ) {
01576               snprintf( textbuf, textlen,
01577                      "attribute \"%s\" not supported in context",
01578                      attr->a_desc->ad_cname.bv_val );
01579               return LDAP_OBJECT_CLASS_VIOLATION;
01580        }
01581 
01582        snprintf( textbuf, textlen,
01583               "attribute \"%s\" not supported!",
01584               attr->a_desc->ad_cname.bv_val );
01585        return LDAP_OBJECT_CLASS_VIOLATION;
01586 }
01587 
01588 #ifdef LDAP_DYNAMIC_OBJECTS
01589 static int dynamicAttribute (
01590        Backend *be,
01591        Entry *e,
01592        Attribute *attr,
01593        const char** text,
01594        char *textbuf, size_t textlen )
01595 {
01596        *text = textbuf;
01597 
01598        if( !SLAP_DYNAMIC(be) ) {
01599               snprintf( textbuf, textlen,
01600                      "attribute \"%s\" not supported in context",
01601                      attr->a_desc->ad_cname.bv_val );
01602               return LDAP_OBJECT_CLASS_VIOLATION;
01603        }
01604 
01605        if( !is_entry_dynamicObject( e ) ) {
01606               snprintf( textbuf, textlen,
01607                      "attribute \"%s\" only allowed in dynamic object",
01608                      attr->a_desc->ad_cname.bv_val );
01609               return LDAP_OBJECT_CLASS_VIOLATION;
01610        }
01611 
01612        return LDAP_SUCCESS;
01613 }
01614 #endif /* LDAP_DYNAMIC_OBJECTS */