1/* $NetBSD$ */ 2 3/* schema_prep.c - load builtin schema */ 4/* OpenLDAP: pkg/ldap/servers/slapd/schema_prep.c,v 1.169.2.14 2010/04/13 20:23:19 kurt Exp */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2010 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 19#include "portable.h" 20 21#include <stdio.h> 22 23#include <ac/ctype.h> 24#include <ac/string.h> 25#include <ac/socket.h> 26 27#include "slap.h" 28 29#define OCDEBUG 0 30 31int schema_init_done = 0; 32 33struct slap_internal_schema slap_schema; 34 35static int 36oidValidate( 37 Syntax *syntax, 38 struct berval *in ) 39{ 40 struct berval val = *in; 41 42 if( val.bv_len == 0 ) { 43 /* disallow empty strings */ 44 return LDAP_INVALID_SYNTAX; 45 } 46 47 if( DESC_LEADCHAR( val.bv_val[0] ) ) { 48 val.bv_val++; 49 val.bv_len--; 50 if ( val.bv_len == 0 ) return LDAP_SUCCESS; 51 52 while( DESC_CHAR( val.bv_val[0] ) ) { 53 val.bv_val++; 54 val.bv_len--; 55 56 if ( val.bv_len == 0 ) return LDAP_SUCCESS; 57 } 58 59 } else { 60 int sep = 0; 61 while( OID_LEADCHAR( val.bv_val[0] ) ) { 62 val.bv_val++; 63 val.bv_len--; 64 65 if ( val.bv_val[-1] != '0' ) { 66 while ( OID_LEADCHAR( val.bv_val[0] )) { 67 val.bv_val++; 68 val.bv_len--; 69 } 70 } 71 72 if( val.bv_len == 0 ) { 73 if( sep == 0 ) break; 74 return LDAP_SUCCESS; 75 } 76 77 if( !OID_SEPARATOR( val.bv_val[0] )) break; 78 79 sep++; 80 val.bv_val++; 81 val.bv_len--; 82 } 83 } 84 85 return LDAP_INVALID_SYNTAX; 86} 87 88 89static int objectClassPretty( 90 Syntax *syntax, 91 struct berval *in, 92 struct berval *out, 93 void *ctx ) 94{ 95 ObjectClass *oc; 96 97 if( oidValidate( NULL, in )) return LDAP_INVALID_SYNTAX; 98 99 oc = oc_bvfind( in ); 100 if( oc == NULL ) return LDAP_INVALID_SYNTAX; 101 102 ber_dupbv_x( out, &oc->soc_cname, ctx ); 103 return LDAP_SUCCESS; 104} 105 106static int 107attributeTypeMatch( 108 int *matchp, 109 slap_mask_t flags, 110 Syntax *syntax, 111 MatchingRule *mr, 112 struct berval *value, 113 void *assertedValue ) 114{ 115 struct berval *a = (struct berval *) assertedValue; 116 AttributeType *at = at_bvfind( value ); 117 AttributeType *asserted = at_bvfind( a ); 118 119 if( asserted == NULL ) { 120 if( OID_LEADCHAR( *a->bv_val ) ) { 121 /* OID form, return FALSE */ 122 *matchp = 1; 123 return LDAP_SUCCESS; 124 } 125 126 /* desc form, return undefined */ 127 return LDAP_INVALID_SYNTAX; 128 } 129 130 if ( at == NULL ) { 131 /* unrecognized stored value */ 132 return LDAP_INVALID_SYNTAX; 133 } 134 135 *matchp = ( asserted != at ); 136 return LDAP_SUCCESS; 137} 138 139static int 140matchingRuleMatch( 141 int *matchp, 142 slap_mask_t flags, 143 Syntax *syntax, 144 MatchingRule *mr, 145 struct berval *value, 146 void *assertedValue ) 147{ 148 struct berval *a = (struct berval *) assertedValue; 149 MatchingRule *mrv = mr_bvfind( value ); 150 MatchingRule *asserted = mr_bvfind( a ); 151 152 if( asserted == NULL ) { 153 if( OID_LEADCHAR( *a->bv_val ) ) { 154 /* OID form, return FALSE */ 155 *matchp = 1; 156 return LDAP_SUCCESS; 157 } 158 159 /* desc form, return undefined */ 160 return LDAP_INVALID_SYNTAX; 161 } 162 163 if ( mrv == NULL ) { 164 /* unrecognized stored value */ 165 return LDAP_INVALID_SYNTAX; 166 } 167 168 *matchp = ( asserted != mrv ); 169 return LDAP_SUCCESS; 170} 171 172static int 173objectClassMatch( 174 int *matchp, 175 slap_mask_t flags, 176 Syntax *syntax, 177 MatchingRule *mr, 178 struct berval *value, 179 void *assertedValue ) 180{ 181 struct berval *a = (struct berval *) assertedValue; 182 ObjectClass *oc = oc_bvfind( value ); 183 ObjectClass *asserted = oc_bvfind( a ); 184 185 if( asserted == NULL ) { 186 if( OID_LEADCHAR( *a->bv_val ) ) { 187 /* OID form, return FALSE */ 188 *matchp = 1; 189 return LDAP_SUCCESS; 190 } 191 192 /* desc form, return undefined */ 193 return LDAP_INVALID_SYNTAX; 194 } 195 196 if ( oc == NULL ) { 197 /* unrecognized stored value */ 198 return LDAP_INVALID_SYNTAX; 199 } 200 201 *matchp = ( asserted != oc ); 202 return LDAP_SUCCESS; 203} 204 205static int 206objectSubClassMatch( 207 int *matchp, 208 slap_mask_t flags, 209 Syntax *syntax, 210 MatchingRule *mr, 211 struct berval *value, 212 void *assertedValue ) 213{ 214 struct berval *a = (struct berval *) assertedValue; 215 ObjectClass *oc = oc_bvfind( value ); 216 ObjectClass *asserted = oc_bvfind( a ); 217 218 if( asserted == NULL ) { 219 if( OID_LEADCHAR( *a->bv_val ) ) { 220 /* OID form, return FALSE */ 221 *matchp = 1; 222 return LDAP_SUCCESS; 223 } 224 225 /* desc form, return undefined */ 226 return LDAP_INVALID_SYNTAX; 227 } 228 229 if ( oc == NULL ) { 230 /* unrecognized stored value */ 231 return LDAP_INVALID_SYNTAX; 232 } 233 234 if( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX( flags ) ) { 235 *matchp = ( asserted != oc ); 236 } else { 237 *matchp = !is_object_subclass( asserted, oc ); 238 } 239 240 return LDAP_SUCCESS; 241} 242 243static int objectSubClassIndexer( 244 slap_mask_t use, 245 slap_mask_t mask, 246 Syntax *syntax, 247 MatchingRule *mr, 248 struct berval *prefix, 249 BerVarray values, 250 BerVarray *keysp, 251 void *ctx ) 252{ 253 int rc, noc, i; 254 BerVarray ocvalues; 255 ObjectClass **socs; 256 257 for( noc=0; values[noc].bv_val != NULL; noc++ ) { 258 /* just count em */; 259 } 260 261 /* over allocate */ 262 socs = slap_sl_malloc( (noc+16) * sizeof( ObjectClass * ), ctx ); 263 264 /* initialize */ 265 for( i=0; i<noc; i++ ) { 266 socs[i] = oc_bvfind( &values[i] ); 267 } 268 269 /* expand values */ 270 for( i=0; i<noc; i++ ) { 271 int j; 272 ObjectClass *oc = socs[i]; 273 if( oc == NULL || oc->soc_sups == NULL ) continue; 274 275 for( j=0; oc->soc_sups[j] != NULL; j++ ) { 276 int found = 0; 277 ObjectClass *sup = oc->soc_sups[j]; 278 int k; 279 280 for( k=0; k<noc; k++ ) { 281 if( sup == socs[k] ) { 282 found++; 283 break; 284 } 285 } 286 287 if( !found ) { 288 socs = slap_sl_realloc( socs, 289 sizeof( ObjectClass * ) * (noc+2), ctx ); 290 291 assert( k == noc ); 292 socs[noc++] = sup; 293 } 294 } 295 } 296 297 ocvalues = slap_sl_malloc( sizeof( struct berval ) * (noc+1), ctx ); 298 /* copy values */ 299 for( i=0; i<noc; i++ ) { 300 if ( socs[i] ) 301 ocvalues[i] = socs[i]->soc_cname; 302 else 303 ocvalues[i] = values[i]; 304 } 305 BER_BVZERO( &ocvalues[i] ); 306 307 rc = octetStringIndexer( use, mask, syntax, mr, 308 prefix, ocvalues, keysp, ctx ); 309 310 slap_sl_free( ocvalues, ctx ); 311 slap_sl_free( socs, ctx ); 312 return rc; 313} 314 315#define objectSubClassFilter octetStringFilter 316 317static ObjectClassSchemaCheckFN rootDseObjectClass; 318static ObjectClassSchemaCheckFN aliasObjectClass; 319static ObjectClassSchemaCheckFN referralObjectClass; 320static ObjectClassSchemaCheckFN subentryObjectClass; 321#ifdef LDAP_DYNAMIC_OBJECTS 322static ObjectClassSchemaCheckFN dynamicObjectClass; 323#endif 324 325static struct slap_schema_oc_map { 326 char *ssom_name; 327 char *ssom_defn; 328 ObjectClassSchemaCheckFN *ssom_check; 329 slap_mask_t ssom_flags; 330 size_t ssom_offset; 331} oc_map[] = { 332 { "top", "( 2.5.6.0 NAME 'top' " 333 "DESC 'top of the superclass chain' " 334 "ABSTRACT MUST objectClass )", 335 0, 0, offsetof(struct slap_internal_schema, si_oc_top) }, 336 { "extensibleObject", "( 1.3.6.1.4.1.1466.101.120.111 " 337 "NAME 'extensibleObject' " 338 "DESC 'RFC4512: extensible object' " 339 "SUP top AUXILIARY )", 340 0, SLAP_OC_OPERATIONAL, 341 offsetof(struct slap_internal_schema, si_oc_extensibleObject) }, 342 { "alias", "( 2.5.6.1 NAME 'alias' " 343 "DESC 'RFC4512: an alias' " 344 "SUP top STRUCTURAL " 345 "MUST aliasedObjectName )", 346 aliasObjectClass, SLAP_OC_ALIAS|SLAP_OC_OPERATIONAL, 347 offsetof(struct slap_internal_schema, si_oc_alias) }, 348 { "referral", "( 2.16.840.1.113730.3.2.6 NAME 'referral' " 349 "DESC 'namedref: named subordinate referral' " 350 "SUP top STRUCTURAL MUST ref )", 351 referralObjectClass, SLAP_OC_REFERRAL|SLAP_OC_OPERATIONAL, 352 offsetof(struct slap_internal_schema, si_oc_referral) }, 353 { "LDAProotDSE", "( 1.3.6.1.4.1.4203.1.4.1 " 354 "NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) " 355 "DESC 'OpenLDAP Root DSE object' " 356 "SUP top STRUCTURAL MAY cn )", 357 rootDseObjectClass, SLAP_OC_OPERATIONAL, 358 offsetof(struct slap_internal_schema, si_oc_rootdse) }, 359 { "subentry", "( 2.5.17.0 NAME 'subentry' " 360 "DESC 'RFC3672: subentry' " 361 "SUP top STRUCTURAL " 362 "MUST ( cn $ subtreeSpecification ) )", 363 subentryObjectClass, SLAP_OC_SUBENTRY|SLAP_OC_OPERATIONAL, 364 offsetof(struct slap_internal_schema, si_oc_subentry) }, 365 { "subschema", "( 2.5.20.1 NAME 'subschema' " 366 "DESC 'RFC4512: controlling subschema (sub)entry' " 367 "AUXILIARY " 368 "MAY ( dITStructureRules $ nameForms $ dITContentRules $ " 369 "objectClasses $ attributeTypes $ matchingRules $ " 370 "matchingRuleUse ) )", 371 subentryObjectClass, SLAP_OC_OPERATIONAL, 372 offsetof(struct slap_internal_schema, si_oc_subschema) }, 373#ifdef LDAP_COLLECTIVE_ATTRIBUTES 374 { "collectiveAttributeSubentry", "( 2.5.17.2 " 375 "NAME 'collectiveAttributeSubentry' " 376 "DESC 'RFC3671: collective attribute subentry' " 377 "AUXILIARY )", 378 subentryObjectClass, 379 SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 380 offsetof( struct slap_internal_schema, 381 si_oc_collectiveAttributeSubentry) }, 382#endif 383#ifdef LDAP_DYNAMIC_OBJECTS 384 { "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 " 385 "NAME 'dynamicObject' " 386 "DESC 'RFC2589: Dynamic Object' " 387 "SUP top AUXILIARY )", 388 dynamicObjectClass, SLAP_OC_DYNAMICOBJECT, 389 offsetof(struct slap_internal_schema, si_oc_dynamicObject) }, 390#endif 391 { "glue", "( 1.3.6.1.4.1.4203.666.3.4 " 392 "NAME 'glue' " 393 "DESC 'Glue Entry' " 394 "SUP top STRUCTURAL )", 395 0, SLAP_OC_GLUE|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 396 offsetof(struct slap_internal_schema, si_oc_glue) }, 397 { "syncConsumerSubentry", "( 1.3.6.1.4.1.4203.666.3.5 " 398 "NAME 'syncConsumerSubentry' " 399 "DESC 'Persistent Info for SyncRepl Consumer' " 400 "AUXILIARY " 401 "MAY syncreplCookie )", 402 0, SLAP_OC_SYNCCONSUMERSUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 403 offsetof(struct slap_internal_schema, si_oc_syncConsumerSubentry) }, 404 { "syncProviderSubentry", "( 1.3.6.1.4.1.4203.666.3.6 " 405 "NAME 'syncProviderSubentry' " 406 "DESC 'Persistent Info for SyncRepl Producer' " 407 "AUXILIARY " 408 "MAY contextCSN )", 409 0, SLAP_OC_SYNCPROVIDERSUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 410 offsetof(struct slap_internal_schema, si_oc_syncProviderSubentry) }, 411 412 { NULL, NULL, NULL, 0, 0 } 413}; 414 415static AttributeTypeSchemaCheckFN rootDseAttribute; 416static AttributeTypeSchemaCheckFN aliasAttribute; 417static AttributeTypeSchemaCheckFN referralAttribute; 418static AttributeTypeSchemaCheckFN subentryAttribute; 419static AttributeTypeSchemaCheckFN administrativeRoleAttribute; 420#ifdef LDAP_DYNAMIC_OBJECTS 421static AttributeTypeSchemaCheckFN dynamicAttribute; 422#endif 423 424static struct slap_schema_ad_map { 425 char *ssam_name; 426 char *ssam_defn; 427 AttributeTypeSchemaCheckFN *ssam_check; 428 slap_mask_t ssam_flags; 429 slap_syntax_validate_func *ssam_syn_validate; 430 slap_syntax_transform_func *ssam_syn_pretty; 431 slap_mr_convert_func *ssam_mr_convert; 432 slap_mr_normalize_func *ssam_mr_normalize; 433 slap_mr_match_func *ssam_mr_match; 434 slap_mr_indexer_func *ssam_mr_indexer; 435 slap_mr_filter_func *ssam_mr_filter; 436 size_t ssam_offset; 437} ad_map[] = { 438 { "objectClass", "( 2.5.4.0 NAME 'objectClass' " 439 "DESC 'RFC4512: object classes of the entity' " 440 "EQUALITY objectIdentifierMatch " 441 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", 442 NULL, SLAP_AT_FINAL, 443 oidValidate, objectClassPretty, 444 NULL, NULL, objectSubClassMatch, 445 objectSubClassIndexer, objectSubClassFilter, 446 offsetof(struct slap_internal_schema, si_ad_objectClass) }, 447 448 /* user entry operational attributes */ 449 { "structuralObjectClass", "( 2.5.21.9 NAME 'structuralObjectClass' " 450 "DESC 'RFC4512: structural object class of entry' " 451 "EQUALITY objectIdentifierMatch " 452 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 " 453 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 454 NULL, 0, 455 oidValidate, objectClassPretty, 456 NULL, NULL, objectSubClassMatch, 457 objectSubClassIndexer, objectSubClassFilter, 458 offsetof(struct slap_internal_schema, si_ad_structuralObjectClass) }, 459 { "createTimestamp", "( 2.5.18.1 NAME 'createTimestamp' " 460 "DESC 'RFC4512: time which object was created' " 461 "EQUALITY generalizedTimeMatch " 462 "ORDERING generalizedTimeOrderingMatch " 463 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 " 464 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 465 NULL, SLAP_AT_MANAGEABLE, 466 NULL, NULL, 467 NULL, NULL, NULL, NULL, NULL, 468 offsetof(struct slap_internal_schema, si_ad_createTimestamp) }, 469 { "modifyTimestamp", "( 2.5.18.2 NAME 'modifyTimestamp' " 470 "DESC 'RFC4512: time which object was last modified' " 471 "EQUALITY generalizedTimeMatch " 472 "ORDERING generalizedTimeOrderingMatch " 473 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 " 474 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 475 NULL, SLAP_AT_MANAGEABLE, 476 NULL, NULL, 477 NULL, NULL, NULL, NULL, NULL, 478 offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) }, 479 { "creatorsName", "( 2.5.18.3 NAME 'creatorsName' " 480 "DESC 'RFC4512: name of creator' " 481 "EQUALITY distinguishedNameMatch " 482 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 483 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 484 NULL, SLAP_AT_MANAGEABLE, 485 NULL, NULL, 486 NULL, NULL, NULL, NULL, NULL, 487 offsetof(struct slap_internal_schema, si_ad_creatorsName) }, 488 { "modifiersName", "( 2.5.18.4 NAME 'modifiersName' " 489 "DESC 'RFC4512: name of last modifier' " 490 "EQUALITY distinguishedNameMatch " 491 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 492 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 493 NULL, SLAP_AT_MANAGEABLE, 494 NULL, NULL, 495 NULL, NULL, NULL, NULL, NULL, 496 offsetof(struct slap_internal_schema, si_ad_modifiersName) }, 497 { "hasSubordinates", "( 2.5.18.9 NAME 'hasSubordinates' " 498 "DESC 'X.501: entry has children' " 499 "EQUALITY booleanMatch " 500 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 " 501 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 502 NULL, SLAP_AT_DYNAMIC, 503 NULL, NULL, 504 NULL, NULL, NULL, NULL, NULL, 505 offsetof(struct slap_internal_schema, si_ad_hasSubordinates) }, 506 { "subschemaSubentry", "( 2.5.18.10 NAME 'subschemaSubentry' " 507 "DESC 'RFC4512: name of controlling subschema entry' " 508 "EQUALITY distinguishedNameMatch " 509 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE " 510 "NO-USER-MODIFICATION USAGE directoryOperation )", 511 NULL, SLAP_AT_DYNAMIC, 512 NULL, NULL, 513 NULL, NULL, NULL, NULL, NULL, 514 offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) }, 515#ifdef LDAP_COLLECTIVE_ATTRIBUTES 516 { "collectiveAttributeSubentries", "( 2.5.18.12 " 517 "NAME 'collectiveAttributeSubentries' " 518 "DESC 'RFC3671: collective attribute subentries' " 519 "EQUALITY distinguishedNameMatch " 520 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 521 "NO-USER-MODIFICATION USAGE directoryOperation )", 522 NULL, SLAP_AT_HIDE, 523 NULL, NULL, 524 NULL, NULL, NULL, NULL, NULL, 525 offsetof(struct slap_internal_schema, si_ad_collectiveSubentries) }, 526 { "collectiveExclusions", "( 2.5.18.7 NAME 'collectiveExclusions' " 527 "DESC 'RFC3671: collective attribute exclusions' " 528 "EQUALITY objectIdentifierMatch " 529 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 " 530 "USAGE directoryOperation )", 531 NULL, SLAP_AT_HIDE, 532 NULL, NULL, 533 NULL, NULL, NULL, NULL, NULL, 534 offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) }, 535#endif 536 537 { "entryDN", "( 1.3.6.1.1.20 NAME 'entryDN' " 538 "DESC 'DN of the entry' " 539 "EQUALITY distinguishedNameMatch " 540 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 541 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 542 NULL, SLAP_AT_DYNAMIC, 543 NULL, NULL, 544 NULL, NULL, NULL, NULL, NULL, 545 offsetof(struct slap_internal_schema, si_ad_entryDN) }, 546 { "entryUUID", "( 1.3.6.1.1.16.4 NAME 'entryUUID' " 547 "DESC 'UUID of the entry' " 548 "EQUALITY UUIDMatch " 549 "ORDERING UUIDOrderingMatch " 550 "SYNTAX 1.3.6.1.1.16.1 " 551 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 552 NULL, SLAP_AT_MANAGEABLE, 553 NULL, NULL, 554 NULL, NULL, NULL, NULL, NULL, 555 offsetof(struct slap_internal_schema, si_ad_entryUUID) }, 556 { "entryCSN", "( 1.3.6.1.4.1.4203.666.1.7 NAME 'entryCSN' " 557 "DESC 'change sequence number of the entry content' " 558 "EQUALITY CSNMatch " 559 "ORDERING CSNOrderingMatch " 560 "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} " 561 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 562 NULL, SLAP_AT_HIDE, 563 NULL, NULL, 564 NULL, NULL, NULL, NULL, NULL, 565 offsetof(struct slap_internal_schema, si_ad_entryCSN) }, 566 { "namingCSN", "( 1.3.6.1.4.1.4203.666.1.13 NAME 'namingCSN' " 567 "DESC 'change sequence number of the entry naming (RDN)' " 568 "EQUALITY CSNMatch " 569 "ORDERING CSNOrderingMatch " 570 "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} " 571 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 572 NULL, SLAP_AT_HIDE, 573 NULL, NULL, 574 NULL, NULL, NULL, NULL, NULL, 575 offsetof(struct slap_internal_schema, si_ad_namingCSN) }, 576 577#ifdef LDAP_SUPERIOR_UUID 578 { "superiorUUID", "( 1.3.6.1.4.1.4203.666.1.11 NAME 'superiorUUID' " 579 "DESC 'UUID of the superior entry' " 580 "EQUALITY UUIDMatch " 581 "ORDERING UUIDOrderingMatch " 582 "SYNTAX 1.3.6.1.1.16.1 " 583 "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", 584 NULL, SLAP_AT_HIDE, 585 NULL, NULL, 586 NULL, NULL, NULL, NULL, NULL, 587 offsetof(struct slap_internal_schema, si_ad_superiorUUID) }, 588#endif 589 590 { "syncreplCookie", "( 1.3.6.1.4.1.4203.666.1.23 " 591 "NAME 'syncreplCookie' " 592 "DESC 'syncrepl Cookie for shadow copy' " 593 "EQUALITY octetStringMatch " 594 "ORDERING octetStringOrderingMatch " 595 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 " 596 "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )", 597 NULL, SLAP_AT_HIDE, 598 NULL, NULL, 599 NULL, NULL, NULL, NULL, NULL, 600 offsetof(struct slap_internal_schema, si_ad_syncreplCookie) }, 601 602 { "contextCSN", "( 1.3.6.1.4.1.4203.666.1.25 " 603 "NAME 'contextCSN' " 604 "DESC 'the largest committed CSN of a context' " 605 "EQUALITY CSNMatch " 606 "ORDERING CSNOrderingMatch " 607 "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1{64} " 608 "NO-USER-MODIFICATION USAGE dSAOperation )", 609 NULL, SLAP_AT_HIDE, 610 NULL, NULL, 611 NULL, NULL, NULL, NULL, NULL, 612 offsetof(struct slap_internal_schema, si_ad_contextCSN) }, 613 614#ifdef LDAP_SYNC_TIMESTAMP 615 { "syncTimestamp", "( 1.3.6.1.4.1.4203.666.1.26 NAME 'syncTimestamp' " 616 "DESC 'Time which object was replicated' " 617 "EQUALITY generalizedTimeMatch " 618 "ORDERING generalizedTimeOrderingMatch " 619 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 " 620 "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )", 621 NULL, 0, 622 NULL, NULL, 623 NULL, NULL, NULL, NULL, NULL, 624 offsetof(struct slap_internal_schema, si_ad_syncTimestamp) }, 625#endif 626 627 /* root DSE attributes */ 628 { "altServer", "( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' " 629 "DESC 'RFC4512: alternative servers' " 630 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dSAOperation )", 631 rootDseAttribute, 0, 632 NULL, NULL, 633 NULL, NULL, NULL, NULL, NULL, 634 offsetof(struct slap_internal_schema, si_ad_altServer) }, 635 { "namingContexts", "( 1.3.6.1.4.1.1466.101.120.5 " 636 "NAME 'namingContexts' " 637 "DESC 'RFC4512: naming contexts' " 638 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dSAOperation )", 639 rootDseAttribute, 0, 640 NULL, NULL, 641 NULL, NULL, NULL, NULL, NULL, 642 offsetof(struct slap_internal_schema, si_ad_namingContexts) }, 643 { "supportedControl", "( 1.3.6.1.4.1.1466.101.120.13 " 644 "NAME 'supportedControl' " 645 "DESC 'RFC4512: supported controls' " 646 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )", 647 rootDseAttribute, 0, 648 NULL, NULL, 649 NULL, NULL, NULL, NULL, NULL, 650 offsetof(struct slap_internal_schema, si_ad_supportedControl) }, 651 { "supportedExtension", "( 1.3.6.1.4.1.1466.101.120.7 " 652 "NAME 'supportedExtension' " 653 "DESC 'RFC4512: supported extended operations' " 654 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 USAGE dSAOperation )", 655 rootDseAttribute, 0, 656 NULL, NULL, 657 NULL, NULL, NULL, NULL, NULL, 658 offsetof(struct slap_internal_schema, si_ad_supportedExtension) }, 659 { "supportedLDAPVersion", "( 1.3.6.1.4.1.1466.101.120.15 " 660 "NAME 'supportedLDAPVersion' " 661 "DESC 'RFC4512: supported LDAP versions' " 662 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dSAOperation )", 663 rootDseAttribute, 0, 664 NULL, NULL, 665 NULL, NULL, NULL, NULL, NULL, 666 offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) }, 667 { "supportedSASLMechanisms", "( 1.3.6.1.4.1.1466.101.120.14 " 668 "NAME 'supportedSASLMechanisms' " 669 "DESC 'RFC4512: supported SASL mechanisms'" 670 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dSAOperation )", 671 rootDseAttribute, 0, 672 NULL, NULL, 673 NULL, NULL, NULL, NULL, NULL, 674 offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) }, 675 { "supportedFeatures", "( 1.3.6.1.4.1.4203.1.3.5 " 676 "NAME 'supportedFeatures' " 677 "DESC 'RFC4512: features supported by the server' " 678 "EQUALITY objectIdentifierMatch " 679 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 " 680 "USAGE dSAOperation )", 681 rootDseAttribute, 0, 682 NULL, NULL, 683 NULL, NULL, NULL, NULL, NULL, 684 offsetof(struct slap_internal_schema, si_ad_supportedFeatures) }, 685 { "monitorContext", "( 1.3.6.1.4.1.4203.666.1.10 " 686 "NAME 'monitorContext' " 687 "DESC 'monitor context' " 688 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 689 "EQUALITY distinguishedNameMatch " 690 "SINGLE-VALUE NO-USER-MODIFICATION " 691 "USAGE dSAOperation )", 692 rootDseAttribute, SLAP_AT_HIDE, 693 NULL, NULL, 694 NULL, NULL, NULL, NULL, NULL, 695 offsetof(struct slap_internal_schema, si_ad_monitorContext) }, 696 { "configContext", "( 1.3.6.1.4.1.4203.1.12.2.1 " 697 "NAME 'configContext' " 698 "DESC 'config context' " 699 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 700 "EQUALITY distinguishedNameMatch " 701 "SINGLE-VALUE NO-USER-MODIFICATION " 702 "USAGE dSAOperation )", 703 rootDseAttribute, SLAP_AT_HIDE, 704 NULL, NULL, 705 NULL, NULL, NULL, NULL, NULL, 706 offsetof(struct slap_internal_schema, si_ad_configContext) }, 707 { "vendorName", "( 1.3.6.1.1.4 NAME 'vendorName' " 708 "DESC 'RFC3045: name of implementation vendor' " 709 "EQUALITY caseExactMatch " 710 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " 711 "SINGLE-VALUE NO-USER-MODIFICATION " 712 "USAGE dSAOperation )", 713 rootDseAttribute, 0, 714 NULL, NULL, 715 NULL, NULL, NULL, NULL, NULL, 716 offsetof(struct slap_internal_schema, si_ad_vendorName) }, 717 { "vendorVersion", "( 1.3.6.1.1.5 NAME 'vendorVersion' " 718 "DESC 'RFC3045: version of implementation' " 719 "EQUALITY caseExactMatch " 720 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " 721 "SINGLE-VALUE NO-USER-MODIFICATION " 722 "USAGE dSAOperation )", 723 rootDseAttribute, 0, 724 NULL, NULL, 725 NULL, NULL, NULL, NULL, NULL, 726 offsetof(struct slap_internal_schema, si_ad_vendorVersion) }, 727 728 /* subentry attributes */ 729 { "administrativeRole", "( 2.5.18.5 NAME 'administrativeRole' " 730 "DESC 'RFC3672: administrative role' " 731 "EQUALITY objectIdentifierMatch " 732 "USAGE directoryOperation " 733 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", 734 administrativeRoleAttribute, SLAP_AT_HIDE, 735 NULL, NULL, 736 NULL, NULL, NULL, NULL, NULL, 737 offsetof(struct slap_internal_schema, si_ad_administrativeRole) }, 738 { "subtreeSpecification", "( 2.5.18.6 NAME 'subtreeSpecification' " 739 "DESC 'RFC3672: subtree specification' " 740 "SINGLE-VALUE " 741 "USAGE directoryOperation " 742 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.45 )", 743 subentryAttribute, SLAP_AT_HIDE, 744 NULL, NULL, 745 NULL, NULL, NULL, NULL, NULL, 746 offsetof(struct slap_internal_schema, si_ad_subtreeSpecification) }, 747 748 /* subschema subentry attributes */ 749 { "dITStructureRules", "( 2.5.21.1 NAME 'dITStructureRules' " 750 "DESC 'RFC4512: DIT structure rules' " 751 "EQUALITY integerFirstComponentMatch " 752 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.17 " 753 "USAGE directoryOperation ) ", 754 subentryAttribute, SLAP_AT_HIDE, 755 NULL, NULL, 756 NULL, NULL, NULL, NULL, NULL, 757 offsetof(struct slap_internal_schema, si_ad_ditStructureRules) }, 758 { "dITContentRules", "( 2.5.21.2 NAME 'dITContentRules' " 759 "DESC 'RFC4512: DIT content rules' " 760 "EQUALITY objectIdentifierFirstComponentMatch " 761 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.16 USAGE directoryOperation )", 762 subentryAttribute, SLAP_AT_HIDE, 763 oidValidate, NULL, 764 NULL, NULL, objectClassMatch, NULL, NULL, 765 offsetof(struct slap_internal_schema, si_ad_ditContentRules) }, 766 { "matchingRules", "( 2.5.21.4 NAME 'matchingRules' " 767 "DESC 'RFC4512: matching rules' " 768 "EQUALITY objectIdentifierFirstComponentMatch " 769 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.30 USAGE directoryOperation )", 770 subentryAttribute, 0, 771 oidValidate, NULL, 772 NULL, NULL, matchingRuleMatch, NULL, NULL, 773 offsetof(struct slap_internal_schema, si_ad_matchingRules) }, 774 { "attributeTypes", "( 2.5.21.5 NAME 'attributeTypes' " 775 "DESC 'RFC4512: attribute types' " 776 "EQUALITY objectIdentifierFirstComponentMatch " 777 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )", 778 subentryAttribute, 0, 779 oidValidate, NULL, 780 NULL, NULL, attributeTypeMatch, NULL, NULL, 781 offsetof(struct slap_internal_schema, si_ad_attributeTypes) }, 782 { "objectClasses", "( 2.5.21.6 NAME 'objectClasses' " 783 "DESC 'RFC4512: object classes' " 784 "EQUALITY objectIdentifierFirstComponentMatch " 785 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )", 786 subentryAttribute, 0, 787 oidValidate, NULL, 788 NULL, NULL, objectClassMatch, NULL, NULL, 789 offsetof(struct slap_internal_schema, si_ad_objectClasses) }, 790 { "nameForms", "( 2.5.21.7 NAME 'nameForms' " 791 "DESC 'RFC4512: name forms ' " 792 "EQUALITY objectIdentifierFirstComponentMatch " 793 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.35 USAGE directoryOperation )", 794 subentryAttribute, SLAP_AT_HIDE, 795 NULL, NULL, 796 NULL, NULL, NULL, NULL, NULL, 797 offsetof(struct slap_internal_schema, si_ad_nameForms) }, 798 { "matchingRuleUse", "( 2.5.21.8 NAME 'matchingRuleUse' " 799 "DESC 'RFC4512: matching rule uses' " 800 "EQUALITY objectIdentifierFirstComponentMatch " 801 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.31 USAGE directoryOperation )", 802 subentryAttribute, 0, 803 oidValidate, NULL, 804 NULL, NULL, matchingRuleMatch, NULL, NULL, 805 offsetof(struct slap_internal_schema, si_ad_matchingRuleUse) }, 806 807 { "ldapSyntaxes", "( 1.3.6.1.4.1.1466.101.120.16 NAME 'ldapSyntaxes' " 808 "DESC 'RFC4512: LDAP syntaxes' " 809 "EQUALITY objectIdentifierFirstComponentMatch " 810 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.54 USAGE directoryOperation )", 811 subentryAttribute, 0, 812 NULL, NULL, 813 NULL, NULL, NULL, NULL, NULL, 814 offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) }, 815 816 /* knowledge information */ 817 { "aliasedObjectName", "( 2.5.4.1 " 818 "NAME ( 'aliasedObjectName' 'aliasedEntryName' ) " 819 "DESC 'RFC4512: name of aliased object' " 820 "EQUALITY distinguishedNameMatch " 821 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )", 822 aliasAttribute, SLAP_AT_FINAL, 823 NULL, NULL, 824 NULL, NULL, NULL, NULL, NULL, 825 offsetof(struct slap_internal_schema, si_ad_aliasedObjectName) }, 826 { "ref", "( 2.16.840.1.113730.3.1.34 NAME 'ref' " 827 "DESC 'RFC3296: subordinate referral URL' " 828 "EQUALITY caseExactMatch " 829 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " 830 "USAGE distributedOperation )", 831 referralAttribute, 0, 832 NULL, NULL, 833 NULL, NULL, NULL, NULL, NULL, 834 offsetof(struct slap_internal_schema, si_ad_ref) }, 835 836 /* access control internals */ 837 { "entry", "( 1.3.6.1.4.1.4203.1.3.1 " 838 "NAME 'entry' " 839 "DESC 'OpenLDAP ACL entry pseudo-attribute' " 840 "SYNTAX 1.3.6.1.4.1.4203.1.1.1 " 841 "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )", 842 NULL, SLAP_AT_HIDE, 843 NULL, NULL, 844 NULL, NULL, NULL, NULL, NULL, 845 offsetof(struct slap_internal_schema, si_ad_entry) }, 846 { "children", "( 1.3.6.1.4.1.4203.1.3.2 " 847 "NAME 'children' " 848 "DESC 'OpenLDAP ACL children pseudo-attribute' " 849 "SYNTAX 1.3.6.1.4.1.4203.1.1.1 " 850 "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )", 851 NULL, SLAP_AT_HIDE, 852 NULL, NULL, 853 NULL, NULL, NULL, NULL, NULL, 854 offsetof(struct slap_internal_schema, si_ad_children) }, 855 856 /* access control externals */ 857 { "authzTo", "( 1.3.6.1.4.1.4203.666.1.8 " 858 "NAME ( 'authzTo' 'saslAuthzTo' ) " 859 "DESC 'proxy authorization targets' " 860 "EQUALITY authzMatch " 861 "SYNTAX 1.3.6.1.4.1.4203.666.2.7 " 862 "X-ORDERED 'VALUES' " 863 "USAGE distributedOperation )", 864 NULL, SLAP_AT_HIDE, 865 NULL, NULL, 866 NULL, NULL, NULL, NULL, NULL, 867 offsetof(struct slap_internal_schema, si_ad_saslAuthzTo) }, 868 { "authzFrom", "( 1.3.6.1.4.1.4203.666.1.9 " 869 "NAME ( 'authzFrom' 'saslAuthzFrom' ) " 870 "DESC 'proxy authorization sources' " 871 "EQUALITY authzMatch " 872 "SYNTAX 1.3.6.1.4.1.4203.666.2.7 " 873 "X-ORDERED 'VALUES' " 874 "USAGE distributedOperation )", 875 NULL, SLAP_AT_HIDE, 876 NULL, NULL, 877 NULL, NULL, NULL, NULL, NULL, 878 offsetof(struct slap_internal_schema, si_ad_saslAuthzFrom) }, 879 880#ifdef LDAP_DYNAMIC_OBJECTS 881 { "entryTtl", "( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' " 882 "DESC 'RFC2589: entry time-to-live' " 883 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE " 884 "NO-USER-MODIFICATION USAGE dSAOperation )", 885 dynamicAttribute, SLAP_AT_MANAGEABLE, 886 NULL, NULL, 887 NULL, NULL, NULL, NULL, NULL, 888 offsetof(struct slap_internal_schema, si_ad_entryTtl) }, 889 { "dynamicSubtrees", "( 1.3.6.1.4.1.1466.101.119.4 " 890 "NAME 'dynamicSubtrees' " 891 "DESC 'RFC2589: dynamic subtrees' " 892 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION " 893 "USAGE dSAOperation )", 894 rootDseAttribute, 0, 895 NULL, NULL, 896 NULL, NULL, NULL, NULL, NULL, 897 offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) }, 898#endif 899 900 /* userApplication attributes (which system schema depends upon) */ 901 { "distinguishedName", "( 2.5.4.49 NAME 'distinguishedName' " 902 "DESC 'RFC4519: common supertype of DN attributes' " 903 "EQUALITY distinguishedNameMatch " 904 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", 905 NULL, SLAP_AT_ABSTRACT, 906 NULL, NULL, 907 NULL, NULL, NULL, NULL, NULL, 908 offsetof(struct slap_internal_schema, si_ad_distinguishedName) }, 909 { "name", "( 2.5.4.41 NAME 'name' " 910 "DESC 'RFC4519: common supertype of name attributes' " 911 "EQUALITY caseIgnoreMatch " 912 "SUBSTR caseIgnoreSubstringsMatch " 913 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )", 914 NULL, SLAP_AT_ABSTRACT, 915 NULL, NULL, 916 NULL, NULL, NULL, NULL, NULL, 917 offsetof(struct slap_internal_schema, si_ad_name) }, 918 { "cn", "( 2.5.4.3 NAME ( 'cn' 'commonName' ) " 919 "DESC 'RFC4519: common name(s) for which the entity is known by' " 920 "SUP name )", 921 NULL, 0, 922 NULL, NULL, 923 NULL, NULL, NULL, NULL, NULL, 924 offsetof(struct slap_internal_schema, si_ad_cn) }, 925 { "uid", "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' ) " 926 "DESC 'RFC4519: user identifier' " 927 "EQUALITY caseIgnoreMatch " 928 "SUBSTR caseIgnoreSubstringsMatch " 929 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )", 930 NULL, 0, 931 NULL, NULL, 932 NULL, NULL, NULL, NULL, NULL, 933 offsetof(struct slap_internal_schema, si_ad_uid) }, 934 { "uidNumber", /* for ldapi:// */ 935 "( 1.3.6.1.1.1.1.0 NAME 'uidNumber' " 936 "DESC 'RFC2307: An integer uniquely identifying a user " 937 "in an administrative domain' " 938 "EQUALITY integerMatch " 939 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", 940 NULL, 0, 941 NULL, NULL, 942 NULL, NULL, NULL, NULL, NULL, 943 offsetof(struct slap_internal_schema, si_ad_uidNumber) }, 944 { "gidNumber", /* for ldapi:// */ 945 "( 1.3.6.1.1.1.1.1 NAME 'gidNumber' " 946 "DESC 'RFC2307: An integer uniquely identifying a group " 947 "in an administrative domain' " 948 "EQUALITY integerMatch " 949 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )", 950 NULL, 0, 951 NULL, NULL, 952 NULL, NULL, NULL, NULL, NULL, 953 offsetof(struct slap_internal_schema, si_ad_gidNumber) }, 954 { "userPassword", "( 2.5.4.35 NAME 'userPassword' " 955 "DESC 'RFC4519/2307: password of user' " 956 "EQUALITY octetStringMatch " 957 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )", 958 NULL, 0, 959 NULL, NULL, 960 NULL, NULL, NULL, NULL, NULL, 961 offsetof(struct slap_internal_schema, si_ad_userPassword) }, 962 963 { "labeledURI", "( 1.3.6.1.4.1.250.1.57 NAME 'labeledURI' " 964 "DESC 'RFC2079: Uniform Resource Identifier with optional label' " 965 "EQUALITY caseExactMatch " 966 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", 967 NULL, 0, 968 NULL, NULL, 969 NULL, NULL, NULL, NULL, NULL, 970 offsetof(struct slap_internal_schema, si_ad_labeledURI) }, 971 972#ifdef SLAPD_AUTHPASSWD 973 { "authPassword", "( 1.3.6.1.4.1.4203.1.3.4 " 974 "NAME 'authPassword' " 975 "DESC 'RFC3112: authentication password attribute' " 976 "EQUALITY 1.3.6.1.4.1.4203.1.2.2 " 977 "SYNTAX 1.3.6.1.4.1.4203.1.1.2 )", 978 NULL, 0, 979 NULL, NULL, 980 NULL, NULL, NULL, NULL, NULL, 981 offsetof(struct slap_internal_schema, si_ad_authPassword) }, 982 { "supportedAuthPasswordSchemes", "( 1.3.6.1.4.1.4203.1.3.3 " 983 "NAME 'supportedAuthPasswordSchemes' " 984 "DESC 'RFC3112: supported authPassword schemes' " 985 "EQUALITY caseExactIA5Match " 986 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} " 987 "USAGE dSAOperation )", 988 subschemaAttribute, 0, 989 NULL, NULL, 990 NULL, NULL, NULL, NULL, NULL, 991 offsetof(struct slap_internal_schema, si_ad_authPasswordSchemes) }, 992#endif 993 994 { "description", "( 2.5.4.13 NAME 'description' " 995 "DESC 'RFC4519: descriptive information' " 996 "EQUALITY caseIgnoreMatch " 997 "SUBSTR caseIgnoreSubstringsMatch " 998 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )", 999 NULL, 0, 1000 NULL, NULL, 1001 NULL, NULL, NULL, NULL, NULL, 1002 offsetof(struct slap_internal_schema, si_ad_description) }, 1003 1004 { "seeAlso", "( 2.5.4.34 NAME 'seeAlso' " 1005 "DESC 'RFC4519: DN of related object' " 1006 "SUP distinguishedName )", 1007 NULL, 0, 1008 NULL, NULL, 1009 NULL, NULL, NULL, NULL, NULL, 1010 offsetof(struct slap_internal_schema, si_ad_seeAlso) }, 1011 1012 { NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 } 1013}; 1014 1015static AttributeType slap_at_undefined = { 1016 { "1.1.1", NULL, "Catchall for undefined attribute types", 1, NULL, 1017 NULL, NULL, NULL, NULL, 1018 0, 0, 0, 1, LDAP_SCHEMA_DSA_OPERATION, NULL }, /* LDAPAttributeType */ 1019 BER_BVC("UNDEFINED"), /* cname */ 1020 NULL, /* sup */ 1021 NULL, /* subtypes */ 1022 NULL, NULL, NULL, NULL, /* matching rules routines */ 1023 NULL, /* syntax (will be set later to "octetString") */ 1024 NULL, /* schema check function */ 1025 NULL, /* oidmacro */ 1026 NULL, /* soidmacro */ 1027 SLAP_AT_ABSTRACT|SLAP_AT_FINAL, /* mask */ 1028 { NULL }, /* next */ 1029 NULL /* attribute description */ 1030 /* mutex (don't know how to initialize it :) */ 1031}; 1032 1033static AttributeType slap_at_proxied = { 1034 { "1.1.1", NULL, "Catchall for undefined proxied attribute types", 1, NULL, 1035 NULL, NULL, NULL, NULL, 1036 0, 0, 0, 0, LDAP_SCHEMA_USER_APPLICATIONS, NULL }, /* LDAPAttributeType */ 1037 BER_BVC("PROXIED"), /* cname */ 1038 NULL, /* sup */ 1039 NULL, /* subtypes */ 1040 NULL, NULL, NULL, NULL, /* matching rules routines (will be set later) */ 1041 NULL, /* syntax (will be set later to "octetString") */ 1042 NULL, /* schema check function */ 1043 NULL, /* oidmacro */ 1044 NULL, /* soidmacro */ 1045 SLAP_AT_ABSTRACT|SLAP_AT_FINAL, /* mask */ 1046 { NULL }, /* next */ 1047 NULL /* attribute description */ 1048 /* mutex (don't know how to initialize it :) */ 1049}; 1050 1051static struct slap_schema_mr_map { 1052 char *ssmm_name; 1053 size_t ssmm_offset; 1054} mr_map[] = { 1055 { "caseExactIA5Match", 1056 offsetof(struct slap_internal_schema, si_mr_caseExactIA5Match) }, 1057 { "caseExactMatch", 1058 offsetof(struct slap_internal_schema, si_mr_caseExactMatch) }, 1059 { "caseExactSubstringsMatch", 1060 offsetof(struct slap_internal_schema, si_mr_caseExactSubstringsMatch) }, 1061 { "distinguishedNameMatch", 1062 offsetof(struct slap_internal_schema, si_mr_distinguishedNameMatch) }, 1063 { "dnSubtreeMatch", 1064 offsetof(struct slap_internal_schema, si_mr_dnSubtreeMatch) }, 1065 { "dnOneLevelMatch", 1066 offsetof(struct slap_internal_schema, si_mr_dnOneLevelMatch) }, 1067 { "dnSubordinateMatch", 1068 offsetof(struct slap_internal_schema, si_mr_dnSubordinateMatch) }, 1069 { "dnSuperiorMatch", 1070 offsetof(struct slap_internal_schema, si_mr_dnSuperiorMatch) }, 1071 { "integerMatch", 1072 offsetof(struct slap_internal_schema, si_mr_integerMatch) }, 1073 { "integerFirstComponentMatch", 1074 offsetof(struct slap_internal_schema, 1075 si_mr_integerFirstComponentMatch) }, 1076 { "objectIdentifierFirstComponentMatch", 1077 offsetof(struct slap_internal_schema, 1078 si_mr_objectIdentifierFirstComponentMatch) }, 1079 { "caseIgnoreMatch", 1080 offsetof(struct slap_internal_schema, si_mr_caseIgnoreMatch) }, 1081 { "caseIgnoreListMatch", 1082 offsetof(struct slap_internal_schema, si_mr_caseIgnoreListMatch) }, 1083 { NULL, 0 } 1084}; 1085 1086static struct slap_schema_syn_map { 1087 char *sssm_name; 1088 size_t sssm_offset; 1089} syn_map[] = { 1090 { "1.3.6.1.4.1.1466.115.121.1.15", 1091 offsetof(struct slap_internal_schema, si_syn_directoryString) }, 1092 { "1.3.6.1.4.1.1466.115.121.1.12", 1093 offsetof(struct slap_internal_schema, si_syn_distinguishedName) }, 1094 { "1.3.6.1.4.1.1466.115.121.1.27", 1095 offsetof(struct slap_internal_schema, si_syn_integer) }, 1096 { "1.3.6.1.4.1.1466.115.121.1.40", 1097 offsetof(struct slap_internal_schema, si_syn_octetString) }, 1098 { "1.3.6.1.4.1.1466.115.121.1.3", 1099 offsetof(struct slap_internal_schema, si_syn_attributeTypeDesc) }, 1100 { "1.3.6.1.4.1.1466.115.121.1.16", 1101 offsetof(struct slap_internal_schema, si_syn_ditContentRuleDesc) }, 1102 { "1.3.6.1.4.1.1466.115.121.1.54", 1103 offsetof(struct slap_internal_schema, si_syn_ldapSyntaxDesc) }, 1104 { "1.3.6.1.4.1.1466.115.121.1.30", 1105 offsetof(struct slap_internal_schema, si_syn_matchingRuleDesc) }, 1106 { "1.3.6.1.4.1.1466.115.121.1.31", 1107 offsetof(struct slap_internal_schema, si_syn_matchingRuleUseDesc) }, 1108 { "1.3.6.1.4.1.1466.115.121.1.35", 1109 offsetof(struct slap_internal_schema, si_syn_nameFormDesc) }, 1110 { "1.3.6.1.4.1.1466.115.121.1.37", 1111 offsetof(struct slap_internal_schema, si_syn_objectClassDesc) }, 1112 { "1.3.6.1.4.1.1466.115.121.1.17", 1113 offsetof(struct slap_internal_schema, si_syn_ditStructureRuleDesc) }, 1114 { NULL, 0 } 1115}; 1116 1117int 1118slap_schema_load( void ) 1119{ 1120 int i; 1121 1122 for( i=0; syn_map[i].sssm_name; i++ ) { 1123 Syntax ** synp = (Syntax **) 1124 &(((char *) &slap_schema)[syn_map[i].sssm_offset]); 1125 1126 assert( *synp == NULL ); 1127 1128 *synp = syn_find( syn_map[i].sssm_name ); 1129 1130 if( *synp == NULL ) { 1131 fprintf( stderr, "slap_schema_load: Syntax: " 1132 "No syntax \"%s\" defined in schema\n", 1133 syn_map[i].sssm_name ); 1134 return LDAP_INVALID_SYNTAX; 1135 } 1136 } 1137 1138 for( i=0; mr_map[i].ssmm_name; i++ ) { 1139 MatchingRule ** mrp = (MatchingRule **) 1140 &(((char *) &slap_schema)[mr_map[i].ssmm_offset]); 1141 1142 assert( *mrp == NULL ); 1143 1144 *mrp = mr_find( mr_map[i].ssmm_name ); 1145 1146 if( *mrp == NULL ) { 1147 fprintf( stderr, "slap_schema_load: MatchingRule: " 1148 "No matching rule \"%s\" defined in schema\n", 1149 mr_map[i].ssmm_name ); 1150 return LDAP_INAPPROPRIATE_MATCHING; 1151 } 1152 } 1153 1154 slap_at_undefined.sat_syntax = slap_schema.si_syn_octetString; 1155 slap_schema.si_at_undefined = &slap_at_undefined; 1156 1157 slap_at_proxied.sat_equality = mr_find( "octetStringMatch" ); 1158 slap_at_proxied.sat_approx = mr_find( "octetStringMatch" ); 1159 slap_at_proxied.sat_ordering = mr_find( "octetStringOrderingMatch" ); 1160 slap_at_proxied.sat_substr = mr_find( "octetStringSubstringsMatch" ); 1161 slap_at_proxied.sat_syntax = slap_schema.si_syn_octetString; 1162 slap_schema.si_at_proxied = &slap_at_proxied; 1163 1164 ldap_pvt_thread_mutex_init( &ad_undef_mutex ); 1165 ldap_pvt_thread_mutex_init( &oc_undef_mutex ); 1166 1167 for( i=0; ad_map[i].ssam_name; i++ ) { 1168 assert( ad_map[i].ssam_defn != NULL ); 1169 { 1170 LDAPAttributeType *at; 1171 int code; 1172 const char *err; 1173 1174 at = ldap_str2attributetype( ad_map[i].ssam_defn, 1175 &code, &err, LDAP_SCHEMA_ALLOW_ALL ); 1176 if ( !at ) { 1177 fprintf( stderr, 1178 "slap_schema_load: AttributeType \"%s\": %s before %s\n", 1179 ad_map[i].ssam_name, ldap_scherr2str(code), err ); 1180 return code; 1181 } 1182 1183 if ( at->at_oid == NULL ) { 1184 fprintf( stderr, "slap_schema_load: " 1185 "AttributeType \"%s\": no OID\n", 1186 ad_map[i].ssam_name ); 1187 ldap_attributetype_free( at ); 1188 return LDAP_OTHER; 1189 } 1190 1191 code = at_add( at, 0, NULL, NULL, &err ); 1192 if ( code ) { 1193 ldap_attributetype_free( at ); 1194 fprintf( stderr, "slap_schema_load: AttributeType " 1195 "\"%s\": %s: \"%s\"\n", 1196 ad_map[i].ssam_name, scherr2str(code), err ); 1197 return code; 1198 } 1199 ldap_memfree( at ); 1200 } 1201 { 1202 int rc; 1203 const char *text; 1204 Syntax *syntax = NULL; 1205 1206 AttributeDescription ** adp = (AttributeDescription **) 1207 &(((char *) &slap_schema)[ad_map[i].ssam_offset]); 1208 1209 assert( *adp == NULL ); 1210 1211 rc = slap_str2ad( ad_map[i].ssam_name, adp, &text ); 1212 if( rc != LDAP_SUCCESS ) { 1213 fprintf( stderr, "slap_schema_load: AttributeType \"%s\": " 1214 "not defined in schema\n", 1215 ad_map[i].ssam_name ); 1216 return rc; 1217 } 1218 1219 if( ad_map[i].ssam_check ) { 1220 /* install check routine */ 1221 (*adp)->ad_type->sat_check = ad_map[i].ssam_check; 1222 } 1223 /* install flags */ 1224 (*adp)->ad_type->sat_flags |= ad_map[i].ssam_flags; 1225 1226 /* install custom syntax routines */ 1227 if( ad_map[i].ssam_syn_validate || 1228 ad_map[i].ssam_syn_pretty ) 1229 { 1230 Syntax *syn; 1231 1232 syntax = (*adp)->ad_type->sat_syntax; 1233 1234 syn = ch_malloc( sizeof( Syntax ) ); 1235 *syn = *syntax; 1236 1237 if( ad_map[i].ssam_syn_validate ) { 1238 syn->ssyn_validate = ad_map[i].ssam_syn_validate; 1239 } 1240 if( ad_map[i].ssam_syn_pretty ) { 1241 syn->ssyn_pretty = ad_map[i].ssam_syn_pretty; 1242 } 1243 1244 (*adp)->ad_type->sat_syntax = syn; 1245 } 1246 1247 /* install custom rule routines */ 1248 if( syntax != NULL || 1249 ad_map[i].ssam_mr_convert || 1250 ad_map[i].ssam_mr_normalize || 1251 ad_map[i].ssam_mr_match || 1252 ad_map[i].ssam_mr_indexer || 1253 ad_map[i].ssam_mr_filter ) 1254 { 1255 MatchingRule *mr = ch_malloc( sizeof( MatchingRule ) ); 1256 *mr = *(*adp)->ad_type->sat_equality; 1257 1258 if ( syntax != NULL ) { 1259 mr->smr_syntax = (*adp)->ad_type->sat_syntax; 1260 } 1261 if ( ad_map[i].ssam_mr_convert ) { 1262 mr->smr_convert = ad_map[i].ssam_mr_convert; 1263 } 1264 if ( ad_map[i].ssam_mr_normalize ) { 1265 mr->smr_normalize = ad_map[i].ssam_mr_normalize; 1266 } 1267 if ( ad_map[i].ssam_mr_match ) { 1268 mr->smr_match = ad_map[i].ssam_mr_match; 1269 } 1270 if ( ad_map[i].ssam_mr_indexer ) { 1271 mr->smr_indexer = ad_map[i].ssam_mr_indexer; 1272 } 1273 if ( ad_map[i].ssam_mr_filter ) { 1274 mr->smr_filter = ad_map[i].ssam_mr_filter; 1275 } 1276 1277 (*adp)->ad_type->sat_equality = mr; 1278 } 1279 } 1280 } 1281 1282 for( i=0; oc_map[i].ssom_name; i++ ) { 1283 assert( oc_map[i].ssom_defn != NULL ); 1284 { 1285 LDAPObjectClass *oc; 1286 int code; 1287 const char *err; 1288 1289 oc = ldap_str2objectclass( oc_map[i].ssom_defn, &code, &err, 1290 LDAP_SCHEMA_ALLOW_ALL ); 1291 if ( !oc ) { 1292 fprintf( stderr, "slap_schema_load: ObjectClass " 1293 "\"%s\": %s before %s\n", 1294 oc_map[i].ssom_name, ldap_scherr2str(code), err ); 1295 return code; 1296 } 1297 1298 if ( oc->oc_oid == NULL ) { 1299 fprintf( stderr, "slap_schema_load: ObjectClass " 1300 "\"%s\": no OID\n", 1301 oc_map[i].ssom_name ); 1302 ldap_objectclass_free( oc ); 1303 return LDAP_OTHER; 1304 } 1305 1306 code = oc_add(oc,0,NULL,NULL,&err); 1307 if ( code ) { 1308 ldap_objectclass_free( oc ); 1309 fprintf( stderr, "slap_schema_load: ObjectClass " 1310 "\"%s\": %s: \"%s\"\n", 1311 oc_map[i].ssom_name, scherr2str(code), err); 1312 return code; 1313 } 1314 ldap_memfree(oc); 1315 1316 } 1317 { 1318 ObjectClass ** ocp = (ObjectClass **) 1319 &(((char *) &slap_schema)[oc_map[i].ssom_offset]); 1320 1321 assert( *ocp == NULL ); 1322 1323 *ocp = oc_find( oc_map[i].ssom_name ); 1324 if( *ocp == NULL ) { 1325 fprintf( stderr, "slap_schema_load: " 1326 "ObjectClass \"%s\": not defined in schema\n", 1327 oc_map[i].ssom_name ); 1328 return LDAP_OBJECT_CLASS_VIOLATION; 1329 } 1330 1331 if( oc_map[i].ssom_check ) { 1332 /* install check routine */ 1333 (*ocp)->soc_check = oc_map[i].ssom_check; 1334 } 1335 /* install flags */ 1336 (*ocp)->soc_flags |= oc_map[i].ssom_flags; 1337 } 1338 } 1339 1340 return LDAP_SUCCESS; 1341} 1342 1343int 1344slap_schema_check( void ) 1345{ 1346 /* we should only be called once after schema_init() was called */ 1347 assert( schema_init_done == 1 ); 1348 1349 /* 1350 * cycle thru attributeTypes to build matchingRuleUse 1351 */ 1352 if ( matching_rule_use_init() ) { 1353 return LDAP_OTHER; 1354 } 1355 1356 ++schema_init_done; 1357 return LDAP_SUCCESS; 1358} 1359 1360static int rootDseObjectClass ( 1361 Backend *be, 1362 Entry *e, 1363 ObjectClass *oc, 1364 const char** text, 1365 char *textbuf, size_t textlen ) 1366{ 1367 *text = textbuf; 1368 1369 if( e->e_nname.bv_len ) { 1370 snprintf( textbuf, textlen, 1371 "objectClass \"%s\" only allowed in the root DSE", 1372 oc->soc_oid ); 1373 return LDAP_OBJECT_CLASS_VIOLATION; 1374 } 1375 1376 /* we should not be called for the root DSE */ 1377 assert( 0 ); 1378 return LDAP_SUCCESS; 1379} 1380 1381static int aliasObjectClass ( 1382 Backend *be, 1383 Entry *e, 1384 ObjectClass *oc, 1385 const char** text, 1386 char *textbuf, size_t textlen ) 1387{ 1388 *text = textbuf; 1389 1390 if( !SLAP_ALIASES(be) ) { 1391 snprintf( textbuf, textlen, 1392 "objectClass \"%s\" not supported in context", 1393 oc->soc_oid ); 1394 return LDAP_OBJECT_CLASS_VIOLATION; 1395 } 1396 1397 return LDAP_SUCCESS; 1398} 1399 1400static int referralObjectClass ( 1401 Backend *be, 1402 Entry *e, 1403 ObjectClass *oc, 1404 const char** text, 1405 char *textbuf, size_t textlen ) 1406{ 1407 *text = textbuf; 1408 1409 if( !SLAP_REFERRALS(be) ) { 1410 snprintf( textbuf, textlen, 1411 "objectClass \"%s\" not supported in context", 1412 oc->soc_oid ); 1413 return LDAP_OBJECT_CLASS_VIOLATION; 1414 } 1415 1416 return LDAP_SUCCESS; 1417} 1418 1419static int subentryObjectClass ( 1420 Backend *be, 1421 Entry *e, 1422 ObjectClass *oc, 1423 const char** text, 1424 char *textbuf, size_t textlen ) 1425{ 1426 *text = textbuf; 1427 1428 if( !SLAP_SUBENTRIES(be) ) { 1429 snprintf( textbuf, textlen, 1430 "objectClass \"%s\" not supported in context", 1431 oc->soc_oid ); 1432 return LDAP_OBJECT_CLASS_VIOLATION; 1433 } 1434 1435 if( oc != slap_schema.si_oc_subentry && !is_entry_subentry( e ) ) { 1436 snprintf( textbuf, textlen, 1437 "objectClass \"%s\" only allowed in subentries", 1438 oc->soc_oid ); 1439 return LDAP_OBJECT_CLASS_VIOLATION; 1440 } 1441 1442 return LDAP_SUCCESS; 1443} 1444 1445#ifdef LDAP_DYNAMIC_OBJECTS 1446static int dynamicObjectClass ( 1447 Backend *be, 1448 Entry *e, 1449 ObjectClass *oc, 1450 const char** text, 1451 char *textbuf, size_t textlen ) 1452{ 1453 *text = textbuf; 1454 1455 if( !SLAP_DYNAMIC(be) ) { 1456 snprintf( textbuf, textlen, 1457 "objectClass \"%s\" not supported in context", 1458 oc->soc_oid ); 1459 return LDAP_OBJECT_CLASS_VIOLATION; 1460 } 1461 1462 return LDAP_SUCCESS; 1463} 1464#endif /* LDAP_DYNAMIC_OBJECTS */ 1465 1466static int rootDseAttribute ( 1467 Backend *be, 1468 Entry *e, 1469 Attribute *attr, 1470 const char** text, 1471 char *textbuf, size_t textlen ) 1472{ 1473 *text = textbuf; 1474 1475 if( e->e_nname.bv_len ) { 1476 snprintf( textbuf, textlen, 1477 "attribute \"%s\" only allowed in the root DSE", 1478 attr->a_desc->ad_cname.bv_val ); 1479 return LDAP_OBJECT_CLASS_VIOLATION; 1480 } 1481 1482 /* we should not be called for the root DSE */ 1483 assert( 0 ); 1484 return LDAP_SUCCESS; 1485} 1486 1487static int aliasAttribute ( 1488 Backend *be, 1489 Entry *e, 1490 Attribute *attr, 1491 const char** text, 1492 char *textbuf, size_t textlen ) 1493{ 1494 *text = textbuf; 1495 1496 if( !SLAP_ALIASES(be) ) { 1497 snprintf( textbuf, textlen, 1498 "attribute \"%s\" not supported in context", 1499 attr->a_desc->ad_cname.bv_val ); 1500 return LDAP_OBJECT_CLASS_VIOLATION; 1501 } 1502 1503 if( !is_entry_alias( e ) ) { 1504 snprintf( textbuf, textlen, 1505 "attribute \"%s\" only allowed in the alias", 1506 attr->a_desc->ad_cname.bv_val ); 1507 return LDAP_OBJECT_CLASS_VIOLATION; 1508 } 1509 1510 return LDAP_SUCCESS; 1511} 1512 1513static int referralAttribute ( 1514 Backend *be, 1515 Entry *e, 1516 Attribute *attr, 1517 const char** text, 1518 char *textbuf, size_t textlen ) 1519{ 1520 *text = textbuf; 1521 1522 if( !SLAP_REFERRALS(be) ) { 1523 snprintf( textbuf, textlen, 1524 "attribute \"%s\" not supported in context", 1525 attr->a_desc->ad_cname.bv_val ); 1526 return LDAP_OBJECT_CLASS_VIOLATION; 1527 } 1528 1529 if( !is_entry_referral( e ) ) { 1530 snprintf( textbuf, textlen, 1531 "attribute \"%s\" only allowed in the referral", 1532 attr->a_desc->ad_cname.bv_val ); 1533 return LDAP_OBJECT_CLASS_VIOLATION; 1534 } 1535 1536 return LDAP_SUCCESS; 1537} 1538 1539static int subentryAttribute ( 1540 Backend *be, 1541 Entry *e, 1542 Attribute *attr, 1543 const char** text, 1544 char *textbuf, size_t textlen ) 1545{ 1546 *text = textbuf; 1547 1548 if( !SLAP_SUBENTRIES(be) ) { 1549 snprintf( textbuf, textlen, 1550 "attribute \"%s\" not supported in context", 1551 attr->a_desc->ad_cname.bv_val ); 1552 return LDAP_OBJECT_CLASS_VIOLATION; 1553 } 1554 1555 if( !is_entry_subentry( e ) ) { 1556 snprintf( textbuf, textlen, 1557 "attribute \"%s\" only allowed in the subentry", 1558 attr->a_desc->ad_cname.bv_val ); 1559 return LDAP_OBJECT_CLASS_VIOLATION; 1560 } 1561 1562 return LDAP_SUCCESS; 1563} 1564 1565static int administrativeRoleAttribute ( 1566 Backend *be, 1567 Entry *e, 1568 Attribute *attr, 1569 const char** text, 1570 char *textbuf, size_t textlen ) 1571{ 1572 *text = textbuf; 1573 1574 if( !SLAP_SUBENTRIES(be) ) { 1575 snprintf( textbuf, textlen, 1576 "attribute \"%s\" not supported in context", 1577 attr->a_desc->ad_cname.bv_val ); 1578 return LDAP_OBJECT_CLASS_VIOLATION; 1579 } 1580 1581 snprintf( textbuf, textlen, 1582 "attribute \"%s\" not supported!", 1583 attr->a_desc->ad_cname.bv_val ); 1584 return LDAP_OBJECT_CLASS_VIOLATION; 1585} 1586 1587#ifdef LDAP_DYNAMIC_OBJECTS 1588static int dynamicAttribute ( 1589 Backend *be, 1590 Entry *e, 1591 Attribute *attr, 1592 const char** text, 1593 char *textbuf, size_t textlen ) 1594{ 1595 *text = textbuf; 1596 1597 if( !SLAP_DYNAMIC(be) ) { 1598 snprintf( textbuf, textlen, 1599 "attribute \"%s\" not supported in context", 1600 attr->a_desc->ad_cname.bv_val ); 1601 return LDAP_OBJECT_CLASS_VIOLATION; 1602 } 1603 1604 if( !is_entry_dynamicObject( e ) ) { 1605 snprintf( textbuf, textlen, 1606 "attribute \"%s\" only allowed in dynamic object", 1607 attr->a_desc->ad_cname.bv_val ); 1608 return LDAP_OBJECT_CLASS_VIOLATION; 1609 } 1610 1611 return LDAP_SUCCESS; 1612} 1613#endif /* LDAP_DYNAMIC_OBJECTS */ 1614