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