1 /* $NetBSD: at.c,v 1.1.1.4 2010/12/12 15:22:17 adam Exp $ */ 2 3 /* at.c - routines for dealing with attribute types */ 4 /* OpenLDAP: pkg/ldap/servers/slapd/at.c,v 1.84.2.11 2010/04/13 20:23:10 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/errno.h> 25 #include <ac/socket.h> 26 #include <ac/string.h> 27 #include <ac/time.h> 28 29 #include "slap.h" 30 31 32 const char * 33 at_syntax( 34 AttributeType *at ) 35 { 36 for ( ; at != NULL; at = at->sat_sup ) { 37 if ( at->sat_syntax_oid ) { 38 return at->sat_syntax_oid; 39 } 40 } 41 42 assert( 0 ); 43 44 return NULL; 45 } 46 47 int 48 is_at_syntax( 49 AttributeType *at, 50 const char *oid ) 51 { 52 const char *syn_oid = at_syntax( at ); 53 54 if ( syn_oid ) { 55 return strcmp( syn_oid, oid ) == 0; 56 } 57 58 return 0; 59 } 60 61 int is_at_subtype( 62 AttributeType *sub, 63 AttributeType *sup ) 64 { 65 for( ; sub != NULL; sub = sub->sat_sup ) { 66 if( sub == sup ) return 1; 67 } 68 69 return 0; 70 } 71 72 struct aindexrec { 73 struct berval air_name; 74 AttributeType *air_at; 75 }; 76 77 static Avlnode *attr_index = NULL; 78 static Avlnode *attr_cache = NULL; 79 static LDAP_STAILQ_HEAD(ATList, AttributeType) attr_list 80 = LDAP_STAILQ_HEAD_INITIALIZER(attr_list); 81 82 /* Last hardcoded attribute registered */ 83 AttributeType *at_sys_tail; 84 85 int at_oc_cache; 86 87 static int 88 attr_index_cmp( 89 const void *v_air1, 90 const void *v_air2 ) 91 { 92 const struct aindexrec *air1 = v_air1; 93 const struct aindexrec *air2 = v_air2; 94 int i = air1->air_name.bv_len - air2->air_name.bv_len; 95 if (i) return i; 96 return (strcasecmp( air1->air_name.bv_val, air2->air_name.bv_val )); 97 } 98 99 static int 100 attr_index_name_cmp( 101 const void *v_type, 102 const void *v_air ) 103 { 104 const struct berval *type = v_type; 105 const struct aindexrec *air = v_air; 106 int i = type->bv_len - air->air_name.bv_len; 107 if (i) return i; 108 return (strncasecmp( type->bv_val, air->air_name.bv_val, type->bv_len )); 109 } 110 111 AttributeType * 112 at_find( const char *name ) 113 { 114 struct berval bv; 115 116 bv.bv_val = (char *)name; 117 bv.bv_len = strlen( name ); 118 119 return at_bvfind( &bv ); 120 } 121 122 AttributeType * 123 at_bvfind( struct berval *name ) 124 { 125 struct aindexrec *air; 126 127 if ( attr_cache ) { 128 air = avl_find( attr_cache, name, attr_index_name_cmp ); 129 if ( air ) return air->air_at; 130 } 131 132 air = avl_find( attr_index, name, attr_index_name_cmp ); 133 134 if ( air ) { 135 if ( air->air_at->sat_flags & SLAP_AT_DELETED ) { 136 air = NULL; 137 } else if (( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) { 138 avl_insert( &attr_cache, (caddr_t) air, 139 attr_index_cmp, avl_dup_error ); 140 } 141 } 142 143 return air != NULL ? air->air_at : NULL; 144 } 145 146 int 147 at_append_to_list( 148 AttributeType *sat, 149 AttributeType ***listp ) 150 { 151 AttributeType **list; 152 AttributeType **list1; 153 int size; 154 155 list = *listp; 156 if ( !list ) { 157 size = 2; 158 list = ch_calloc(size, sizeof(AttributeType *)); 159 if ( !list ) { 160 return -1; 161 } 162 } else { 163 size = 0; 164 list1 = *listp; 165 while ( *list1 ) { 166 size++; 167 list1++; 168 } 169 size += 2; 170 list1 = ch_realloc(list, size*sizeof(AttributeType *)); 171 if ( !list1 ) { 172 return -1; 173 } 174 list = list1; 175 } 176 list[size-2] = sat; 177 list[size-1] = NULL; 178 *listp = list; 179 return 0; 180 } 181 182 int 183 at_delete_from_list( 184 int pos, 185 AttributeType ***listp ) 186 { 187 AttributeType **list; 188 AttributeType **list1; 189 int i; 190 int j; 191 192 if ( pos < 0 ) { 193 return -2; 194 } 195 list = *listp; 196 for ( i=0; list[i]; i++ ) 197 ; 198 if ( pos >= i ) { 199 return -2; 200 } 201 for ( i=pos, j=pos+1; list[j]; i++, j++ ) { 202 list[i] = list[j]; 203 } 204 list[i] = NULL; 205 /* Tell the runtime this can be shrinked */ 206 list1 = ch_realloc(list, (i+1)*sizeof(AttributeType **)); 207 if ( !list1 ) { 208 return -1; 209 } 210 *listp = list1; 211 return 0; 212 } 213 214 int 215 at_find_in_list( 216 AttributeType *sat, 217 AttributeType **list ) 218 { 219 int i; 220 221 if ( !list ) { 222 return -1; 223 } 224 for ( i=0; list[i]; i++ ) { 225 if ( sat == list[i] ) { 226 return i; 227 } 228 } 229 return -1; 230 } 231 232 static void 233 at_delete_names( AttributeType *at ) 234 { 235 char **names = at->sat_names; 236 237 while (*names) { 238 struct aindexrec tmpair, *air; 239 240 ber_str2bv( *names, 0, 0, &tmpair.air_name ); 241 tmpair.air_at = at; 242 air = (struct aindexrec *)avl_delete( &attr_index, 243 (caddr_t)&tmpair, attr_index_cmp ); 244 assert( air != NULL ); 245 ldap_memfree( air ); 246 names++; 247 } 248 } 249 250 /* Mark the attribute as deleted, remove from list, and remove all its 251 * names from the AVL tree. Leave the OID in the tree. 252 */ 253 void 254 at_delete( AttributeType *at ) 255 { 256 at->sat_flags |= SLAP_AT_DELETED; 257 258 LDAP_STAILQ_REMOVE(&attr_list, at, AttributeType, sat_next); 259 260 at_delete_names( at ); 261 } 262 263 static void 264 at_clean( AttributeType *a ) 265 { 266 if ( a->sat_equality ) { 267 MatchingRule *mr; 268 269 mr = mr_find( a->sat_equality->smr_oid ); 270 assert( mr != NULL ); 271 if ( mr != a->sat_equality ) { 272 ch_free( a->sat_equality ); 273 a->sat_equality = NULL; 274 } 275 } 276 277 assert( a->sat_syntax != NULL ); 278 if ( a->sat_syntax != NULL ) { 279 Syntax *syn; 280 281 syn = syn_find( a->sat_syntax->ssyn_oid ); 282 assert( syn != NULL ); 283 if ( syn != a->sat_syntax ) { 284 ch_free( a->sat_syntax ); 285 a->sat_syntax = NULL; 286 } 287 } 288 289 if ( a->sat_oidmacro ) { 290 ldap_memfree( a->sat_oidmacro ); 291 a->sat_oidmacro = NULL; 292 } 293 if ( a->sat_soidmacro ) { 294 ldap_memfree( a->sat_soidmacro ); 295 a->sat_soidmacro = NULL; 296 } 297 if ( a->sat_subtypes ) { 298 ldap_memfree( a->sat_subtypes ); 299 a->sat_subtypes = NULL; 300 } 301 } 302 303 static void 304 at_destroy_one( void *v ) 305 { 306 struct aindexrec *air = v; 307 AttributeType *a = air->air_at; 308 309 at_clean( a ); 310 ad_destroy(a->sat_ad); 311 ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex); 312 ldap_attributetype_free((LDAPAttributeType *)a); 313 ldap_memfree(air); 314 } 315 316 void 317 at_destroy( void ) 318 { 319 AttributeType *a; 320 321 while( !LDAP_STAILQ_EMPTY(&attr_list) ) { 322 a = LDAP_STAILQ_FIRST(&attr_list); 323 LDAP_STAILQ_REMOVE_HEAD(&attr_list, sat_next); 324 325 at_delete_names( a ); 326 } 327 328 avl_free(attr_index, at_destroy_one); 329 330 if ( slap_schema.si_at_undefined ) { 331 ad_destroy(slap_schema.si_at_undefined->sat_ad); 332 } 333 334 if ( slap_schema.si_at_proxied ) { 335 ad_destroy(slap_schema.si_at_proxied->sat_ad); 336 } 337 } 338 339 int 340 at_start( AttributeType **at ) 341 { 342 assert( at != NULL ); 343 344 *at = LDAP_STAILQ_FIRST(&attr_list); 345 346 return (*at != NULL); 347 } 348 349 int 350 at_next( AttributeType **at ) 351 { 352 assert( at != NULL ); 353 354 #if 0 /* pedantic check: don't use this */ 355 { 356 AttributeType *tmp = NULL; 357 358 LDAP_STAILQ_FOREACH(tmp,&attr_list,sat_next) { 359 if ( tmp == *at ) { 360 break; 361 } 362 } 363 364 assert( tmp != NULL ); 365 } 366 #endif 367 368 *at = LDAP_STAILQ_NEXT(*at,sat_next); 369 370 return (*at != NULL); 371 } 372 373 /* 374 * check whether the two attributeTypes actually __are__ identical, 375 * or rather inconsistent 376 */ 377 static int 378 at_check_dup( 379 AttributeType *sat, 380 AttributeType *new_sat ) 381 { 382 if ( new_sat->sat_oid != NULL ) { 383 if ( sat->sat_oid == NULL ) { 384 return SLAP_SCHERR_ATTR_INCONSISTENT; 385 } 386 387 if ( strcmp( sat->sat_oid, new_sat->sat_oid ) != 0 ) { 388 return SLAP_SCHERR_ATTR_INCONSISTENT; 389 } 390 391 } else { 392 if ( sat->sat_oid != NULL ) { 393 return SLAP_SCHERR_ATTR_INCONSISTENT; 394 } 395 } 396 397 if ( new_sat->sat_names ) { 398 int i; 399 400 if ( sat->sat_names == NULL ) { 401 return SLAP_SCHERR_ATTR_INCONSISTENT; 402 } 403 404 for ( i = 0; new_sat->sat_names[ i ]; i++ ) { 405 if ( sat->sat_names[ i ] == NULL ) { 406 return SLAP_SCHERR_ATTR_INCONSISTENT; 407 } 408 409 if ( strcasecmp( sat->sat_names[ i ], 410 new_sat->sat_names[ i ] ) != 0 ) 411 { 412 return SLAP_SCHERR_ATTR_INCONSISTENT; 413 } 414 } 415 } else { 416 if ( sat->sat_names != NULL ) { 417 return SLAP_SCHERR_ATTR_INCONSISTENT; 418 } 419 } 420 421 return SLAP_SCHERR_ATTR_DUP; 422 } 423 424 static struct aindexrec *air_old; 425 426 static int 427 at_dup_error( void *left, void *right ) 428 { 429 air_old = left; 430 return -1; 431 } 432 433 static int 434 at_insert( 435 AttributeType **rat, 436 AttributeType *prev, 437 const char **err ) 438 { 439 struct aindexrec *air; 440 char **names = NULL; 441 AttributeType *sat = *rat; 442 443 if ( sat->sat_oid ) { 444 air = (struct aindexrec *) 445 ch_calloc( 1, sizeof(struct aindexrec) ); 446 ber_str2bv( sat->sat_oid, 0, 0, &air->air_name ); 447 air->air_at = sat; 448 air_old = NULL; 449 450 if ( avl_insert( &attr_index, (caddr_t) air, 451 attr_index_cmp, at_dup_error ) ) 452 { 453 AttributeType *old_sat; 454 int rc; 455 456 *err = sat->sat_oid; 457 458 assert( air_old != NULL ); 459 old_sat = air_old->air_at; 460 461 /* replacing a deleted definition? */ 462 if ( old_sat->sat_flags & SLAP_AT_DELETED ) { 463 AttributeType tmp; 464 AttributeDescription *ad; 465 466 /* Keep old oid, free new oid; 467 * Keep old ads, free new ads; 468 * Keep old ad_mutex, free new ad_mutex; 469 * Keep new everything else, free old 470 */ 471 tmp = *old_sat; 472 *old_sat = *sat; 473 old_sat->sat_oid = tmp.sat_oid; 474 tmp.sat_oid = sat->sat_oid; 475 old_sat->sat_ad = tmp.sat_ad; 476 tmp.sat_ad = sat->sat_ad; 477 old_sat->sat_ad_mutex = tmp.sat_ad_mutex; 478 tmp.sat_ad_mutex = sat->sat_ad_mutex; 479 *sat = tmp; 480 481 /* Check for basic ad pointing at old cname */ 482 for ( ad = old_sat->sat_ad; ad; ad=ad->ad_next ) { 483 if ( ad->ad_cname.bv_val == sat->sat_cname.bv_val ) { 484 ad->ad_cname = old_sat->sat_cname; 485 break; 486 } 487 } 488 489 at_clean( sat ); 490 at_destroy_one( air ); 491 492 air = air_old; 493 sat = old_sat; 494 *rat = sat; 495 } else { 496 ldap_memfree( air ); 497 498 rc = at_check_dup( old_sat, sat ); 499 500 return rc; 501 } 502 } 503 /* FIX: temporal consistency check */ 504 at_bvfind( &air->air_name ); 505 } 506 507 names = sat->sat_names; 508 if ( names ) { 509 while ( *names ) { 510 air = (struct aindexrec *) 511 ch_calloc( 1, sizeof(struct aindexrec) ); 512 ber_str2bv( *names, 0, 0, &air->air_name ); 513 air->air_at = sat; 514 if ( avl_insert( &attr_index, (caddr_t) air, 515 attr_index_cmp, avl_dup_error ) ) 516 { 517 AttributeType *old_sat; 518 int rc; 519 520 *err = *names; 521 522 old_sat = at_bvfind( &air->air_name ); 523 assert( old_sat != NULL ); 524 rc = at_check_dup( old_sat, sat ); 525 526 ldap_memfree(air); 527 528 while ( names > sat->sat_names ) { 529 struct aindexrec tmpair; 530 531 names--; 532 ber_str2bv( *names, 0, 0, &tmpair.air_name ); 533 tmpair.air_at = sat; 534 air = (struct aindexrec *)avl_delete( &attr_index, 535 (caddr_t)&tmpair, attr_index_cmp ); 536 assert( air != NULL ); 537 ldap_memfree( air ); 538 } 539 540 if ( sat->sat_oid ) { 541 struct aindexrec tmpair; 542 543 ber_str2bv( sat->sat_oid, 0, 0, &tmpair.air_name ); 544 tmpair.air_at = sat; 545 air = (struct aindexrec *)avl_delete( &attr_index, 546 (caddr_t)&tmpair, attr_index_cmp ); 547 assert( air != NULL ); 548 ldap_memfree( air ); 549 } 550 551 return rc; 552 } 553 /* FIX: temporal consistency check */ 554 at_bvfind(&air->air_name); 555 names++; 556 } 557 } 558 559 if ( sat->sat_oid ) { 560 slap_ad_undef_promote( sat->sat_oid, sat ); 561 } 562 563 names = sat->sat_names; 564 if ( names ) { 565 while ( *names ) { 566 slap_ad_undef_promote( *names, sat ); 567 names++; 568 } 569 } 570 571 if ( sat->sat_flags & SLAP_AT_HARDCODE ) { 572 prev = at_sys_tail; 573 at_sys_tail = sat; 574 } 575 if ( prev ) { 576 LDAP_STAILQ_INSERT_AFTER( &attr_list, prev, sat, sat_next ); 577 } else { 578 LDAP_STAILQ_INSERT_TAIL( &attr_list, sat, sat_next ); 579 } 580 581 return 0; 582 } 583 584 int 585 at_add( 586 LDAPAttributeType *at, 587 int user, 588 AttributeType **rsat, 589 AttributeType *prev, 590 const char **err ) 591 { 592 AttributeType *sat = NULL; 593 MatchingRule *mr = NULL; 594 Syntax *syn = NULL; 595 int i; 596 int code = LDAP_SUCCESS; 597 char *cname = NULL; 598 char *oidm = NULL; 599 char *soidm = NULL; 600 601 if ( !at->at_oid ) { 602 *err = ""; 603 return SLAP_SCHERR_ATTR_INCOMPLETE; 604 } 605 606 if ( !OID_LEADCHAR( at->at_oid[0] )) { 607 char *oid; 608 609 /* Expand OID macros */ 610 oid = oidm_find( at->at_oid ); 611 if ( !oid ) { 612 *err = at->at_oid; 613 return SLAP_SCHERR_OIDM; 614 } 615 if ( oid != at->at_oid ) { 616 oidm = at->at_oid; 617 at->at_oid = oid; 618 } 619 } 620 621 if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) { 622 char *oid; 623 624 /* Expand OID macros */ 625 oid = oidm_find( at->at_syntax_oid ); 626 if ( !oid ) { 627 *err = at->at_syntax_oid; 628 code = SLAP_SCHERR_OIDM; 629 goto error_return; 630 } 631 if ( oid != at->at_syntax_oid ) { 632 soidm = at->at_syntax_oid; 633 at->at_syntax_oid = oid; 634 } 635 } 636 637 if ( at->at_names && at->at_names[0] ) { 638 int i; 639 640 for( i=0; at->at_names[i]; i++ ) { 641 if( !slap_valid_descr( at->at_names[i] ) ) { 642 *err = at->at_names[i]; 643 code = SLAP_SCHERR_BAD_DESCR; 644 goto error_return; 645 } 646 } 647 648 cname = at->at_names[0]; 649 650 } else { 651 cname = at->at_oid; 652 653 } 654 655 *err = cname; 656 657 if ( !at->at_usage && at->at_no_user_mod ) { 658 /* user attribute must be modifable */ 659 code = SLAP_SCHERR_ATTR_BAD_USAGE; 660 goto error_return; 661 } 662 663 if ( at->at_collective ) { 664 if( at->at_usage ) { 665 /* collective attributes cannot be operational */ 666 code = SLAP_SCHERR_ATTR_BAD_USAGE; 667 goto error_return; 668 } 669 670 if( at->at_single_value ) { 671 /* collective attributes cannot be single-valued */ 672 code = SLAP_SCHERR_ATTR_BAD_USAGE; 673 goto error_return; 674 } 675 } 676 677 sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) ); 678 AC_MEMCPY( &sat->sat_atype, at, sizeof(LDAPAttributeType)); 679 680 sat->sat_cname.bv_val = cname; 681 sat->sat_cname.bv_len = strlen( cname ); 682 sat->sat_oidmacro = oidm; 683 sat->sat_soidmacro = soidm; 684 ldap_pvt_thread_mutex_init(&sat->sat_ad_mutex); 685 686 if ( at->at_sup_oid ) { 687 AttributeType *supsat = at_find(at->at_sup_oid); 688 689 if ( supsat == NULL ) { 690 *err = at->at_sup_oid; 691 code = SLAP_SCHERR_ATTR_NOT_FOUND; 692 goto error_return; 693 } 694 695 sat->sat_sup = supsat; 696 697 if ( at_append_to_list(sat, &supsat->sat_subtypes) ) { 698 code = SLAP_SCHERR_OUTOFMEM; 699 goto error_return; 700 } 701 702 if ( sat->sat_usage != supsat->sat_usage ) { 703 /* subtypes must have same usage as their SUP */ 704 code = SLAP_SCHERR_ATTR_BAD_USAGE; 705 goto error_return; 706 } 707 708 if ( supsat->sat_obsolete && !sat->sat_obsolete ) { 709 /* subtypes must be obsolete if super is */ 710 code = SLAP_SCHERR_ATTR_BAD_SUP; 711 goto error_return; 712 } 713 714 if ( sat->sat_flags & SLAP_AT_FINAL ) { 715 /* cannot subtype a "final" attribute type */ 716 code = SLAP_SCHERR_ATTR_BAD_SUP; 717 goto error_return; 718 } 719 } 720 721 /* 722 * Inherit definitions from superiors. We only check the 723 * direct superior since that one has already inherited from 724 * its own superiorss 725 */ 726 if ( sat->sat_sup ) { 727 Syntax *syn = syn_find(sat->sat_sup->sat_syntax->ssyn_oid); 728 if ( syn != sat->sat_sup->sat_syntax ) { 729 sat->sat_syntax = ch_malloc( sizeof( Syntax )); 730 *sat->sat_syntax = *sat->sat_sup->sat_syntax; 731 } else { 732 sat->sat_syntax = sat->sat_sup->sat_syntax; 733 } 734 if ( sat->sat_sup->sat_equality ) { 735 MatchingRule *mr = mr_find( sat->sat_sup->sat_equality->smr_oid ); 736 if ( mr != sat->sat_sup->sat_equality ) { 737 sat->sat_equality = ch_malloc( sizeof( MatchingRule )); 738 *sat->sat_equality = *sat->sat_sup->sat_equality; 739 } else { 740 sat->sat_equality = sat->sat_sup->sat_equality; 741 } 742 } 743 sat->sat_approx = sat->sat_sup->sat_approx; 744 sat->sat_ordering = sat->sat_sup->sat_ordering; 745 sat->sat_substr = sat->sat_sup->sat_substr; 746 } 747 748 /* 749 * check for X-ORDERED attributes 750 */ 751 if ( sat->sat_extensions ) { 752 for (i=0; sat->sat_extensions[i]; i++) { 753 if (!strcasecmp( sat->sat_extensions[i]->lsei_name, 754 "X-ORDERED" ) && sat->sat_extensions[i]->lsei_values ) { 755 if ( !strcasecmp( sat->sat_extensions[i]->lsei_values[0], 756 "VALUES" )) { 757 sat->sat_flags |= SLAP_AT_ORDERED_VAL; 758 break; 759 } else if ( !strcasecmp( sat->sat_extensions[i]->lsei_values[0], 760 "SIBLINGS" )) { 761 sat->sat_flags |= SLAP_AT_ORDERED_SIB; 762 break; 763 } 764 } 765 } 766 } 767 768 if ( !user ) 769 sat->sat_flags |= SLAP_AT_HARDCODE; 770 771 if ( at->at_syntax_oid ) { 772 syn = syn_find(sat->sat_syntax_oid); 773 if ( syn == NULL ) { 774 *err = sat->sat_syntax_oid; 775 code = SLAP_SCHERR_SYN_NOT_FOUND; 776 goto error_return; 777 } 778 779 if ( sat->sat_syntax != NULL && sat->sat_syntax != syn ) { 780 /* BEWARE: no loop detection! */ 781 if ( syn_is_sup( sat->sat_syntax, syn ) ) { 782 code = SLAP_SCHERR_ATTR_BAD_SUP; 783 goto error_return; 784 } 785 } 786 787 sat->sat_syntax = syn; 788 789 } else if ( sat->sat_syntax == NULL ) { 790 code = SLAP_SCHERR_ATTR_INCOMPLETE; 791 goto error_return; 792 } 793 794 if ( sat->sat_equality_oid ) { 795 mr = mr_find(sat->sat_equality_oid); 796 797 if( mr == NULL ) { 798 *err = sat->sat_equality_oid; 799 code = SLAP_SCHERR_MR_NOT_FOUND; 800 goto error_return; 801 } 802 803 if(( mr->smr_usage & SLAP_MR_EQUALITY ) != SLAP_MR_EQUALITY ) { 804 *err = sat->sat_equality_oid; 805 code = SLAP_SCHERR_ATTR_BAD_MR; 806 goto error_return; 807 } 808 809 if( sat->sat_syntax != mr->smr_syntax ) { 810 if( mr->smr_compat_syntaxes == NULL ) { 811 *err = sat->sat_equality_oid; 812 code = SLAP_SCHERR_ATTR_BAD_MR; 813 goto error_return; 814 } 815 816 for(i=0; mr->smr_compat_syntaxes[i]; i++) { 817 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) { 818 i = -1; 819 break; 820 } 821 } 822 823 if( i >= 0 ) { 824 *err = sat->sat_equality_oid; 825 code = SLAP_SCHERR_ATTR_BAD_MR; 826 goto error_return; 827 } 828 } 829 830 sat->sat_equality = mr; 831 sat->sat_approx = mr->smr_associated; 832 } 833 834 if ( sat->sat_ordering_oid ) { 835 if( !sat->sat_equality ) { 836 *err = sat->sat_ordering_oid; 837 code = SLAP_SCHERR_ATTR_BAD_MR; 838 goto error_return; 839 } 840 841 mr = mr_find(sat->sat_ordering_oid); 842 843 if( mr == NULL ) { 844 *err = sat->sat_ordering_oid; 845 code = SLAP_SCHERR_MR_NOT_FOUND; 846 goto error_return; 847 } 848 849 if(( mr->smr_usage & SLAP_MR_ORDERING ) != SLAP_MR_ORDERING ) { 850 *err = sat->sat_ordering_oid; 851 code = SLAP_SCHERR_ATTR_BAD_MR; 852 goto error_return; 853 } 854 855 if( sat->sat_syntax != mr->smr_syntax ) { 856 if( mr->smr_compat_syntaxes == NULL ) { 857 *err = sat->sat_ordering_oid; 858 code = SLAP_SCHERR_ATTR_BAD_MR; 859 goto error_return; 860 } 861 862 for(i=0; mr->smr_compat_syntaxes[i]; i++) { 863 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) { 864 i = -1; 865 break; 866 } 867 } 868 869 if( i >= 0 ) { 870 *err = sat->sat_ordering_oid; 871 code = SLAP_SCHERR_ATTR_BAD_MR; 872 goto error_return; 873 } 874 } 875 876 sat->sat_ordering = mr; 877 } 878 879 if ( sat->sat_substr_oid ) { 880 if( !sat->sat_equality ) { 881 *err = sat->sat_substr_oid; 882 code = SLAP_SCHERR_ATTR_BAD_MR; 883 goto error_return; 884 } 885 886 mr = mr_find(sat->sat_substr_oid); 887 888 if( mr == NULL ) { 889 *err = sat->sat_substr_oid; 890 code = SLAP_SCHERR_MR_NOT_FOUND; 891 goto error_return; 892 } 893 894 if(( mr->smr_usage & SLAP_MR_SUBSTR ) != SLAP_MR_SUBSTR ) { 895 *err = sat->sat_substr_oid; 896 code = SLAP_SCHERR_ATTR_BAD_MR; 897 goto error_return; 898 } 899 900 /* due to funky LDAP builtin substring rules, 901 * we check against the equality rule assertion 902 * syntax and compat syntaxes instead of those 903 * associated with the substrings rule. 904 */ 905 if( sat->sat_syntax != sat->sat_equality->smr_syntax ) { 906 if( sat->sat_equality->smr_compat_syntaxes == NULL ) { 907 *err = sat->sat_substr_oid; 908 code = SLAP_SCHERR_ATTR_BAD_MR; 909 goto error_return; 910 } 911 912 for(i=0; sat->sat_equality->smr_compat_syntaxes[i]; i++) { 913 if( sat->sat_syntax == 914 sat->sat_equality->smr_compat_syntaxes[i] ) 915 { 916 i = -1; 917 break; 918 } 919 } 920 921 if( i >= 0 ) { 922 *err = sat->sat_substr_oid; 923 code = SLAP_SCHERR_ATTR_BAD_MR; 924 goto error_return; 925 } 926 } 927 928 sat->sat_substr = mr; 929 } 930 931 code = at_insert( &sat, prev, err ); 932 if ( code != 0 ) { 933 error_return:; 934 if ( sat ) { 935 ldap_pvt_thread_mutex_destroy( &sat->sat_ad_mutex ); 936 ch_free( sat ); 937 } 938 939 if ( oidm ) { 940 SLAP_FREE( at->at_oid ); 941 at->at_oid = oidm; 942 } 943 944 if ( soidm ) { 945 SLAP_FREE( at->at_syntax_oid ); 946 at->at_syntax_oid = soidm; 947 } 948 949 } else if ( rsat ) { 950 *rsat = sat; 951 } 952 953 return code; 954 } 955 956 #ifdef LDAP_DEBUG 957 #ifdef SLAPD_UNUSED 958 static int 959 at_index_printnode( void *v_air, void *ignore ) 960 { 961 struct aindexrec *air = v_air; 962 printf("%s = %s\n", 963 air->air_name.bv_val, 964 ldap_attributetype2str(&air->air_at->sat_atype) ); 965 return( 0 ); 966 } 967 968 static void 969 at_index_print( void ) 970 { 971 printf("Printing attribute type index:\n"); 972 (void) avl_apply( attr_index, at_index_printnode, 0, -1, AVL_INORDER ); 973 } 974 #endif 975 #endif 976 977 void 978 at_unparse( BerVarray *res, AttributeType *start, AttributeType *end, int sys ) 979 { 980 AttributeType *at; 981 int i, num; 982 struct berval bv, *bva = NULL, idx; 983 char ibuf[32]; 984 985 if ( !start ) 986 start = LDAP_STAILQ_FIRST( &attr_list ); 987 988 /* count the result size */ 989 i = 0; 990 for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) { 991 if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break; 992 i++; 993 if ( at == end ) break; 994 } 995 if (!i) return; 996 997 num = i; 998 bva = ch_malloc( (num+1) * sizeof(struct berval) ); 999 BER_BVZERO( bva ); 1000 idx.bv_val = ibuf; 1001 if ( sys ) { 1002 idx.bv_len = 0; 1003 ibuf[0] = '\0'; 1004 } 1005 i = 0; 1006 for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) { 1007 LDAPAttributeType lat, *latp; 1008 if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break; 1009 if ( at->sat_oidmacro || at->sat_soidmacro ) { 1010 lat = at->sat_atype; 1011 if ( at->sat_oidmacro ) 1012 lat.at_oid = at->sat_oidmacro; 1013 if ( at->sat_soidmacro ) 1014 lat.at_syntax_oid = at->sat_soidmacro; 1015 latp = ⪫ 1016 } else { 1017 latp = &at->sat_atype; 1018 } 1019 if ( ldap_attributetype2bv( latp, &bv ) == NULL ) { 1020 ber_bvarray_free( bva ); 1021 } 1022 if ( !sys ) { 1023 idx.bv_len = sprintf(idx.bv_val, "{%d}", i); 1024 } 1025 bva[i].bv_len = idx.bv_len + bv.bv_len; 1026 bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 ); 1027 strcpy( bva[i].bv_val, ibuf ); 1028 strcpy( bva[i].bv_val + idx.bv_len, bv.bv_val ); 1029 i++; 1030 bva[i].bv_val = NULL; 1031 ldap_memfree( bv.bv_val ); 1032 if ( at == end ) break; 1033 } 1034 *res = bva; 1035 } 1036 1037 int 1038 at_schema_info( Entry *e ) 1039 { 1040 AttributeDescription *ad_attributeTypes = slap_schema.si_ad_attributeTypes; 1041 AttributeType *at; 1042 struct berval val; 1043 struct berval nval; 1044 1045 LDAP_STAILQ_FOREACH(at,&attr_list,sat_next) { 1046 if( at->sat_flags & SLAP_AT_HIDE ) continue; 1047 1048 if ( ldap_attributetype2bv( &at->sat_atype, &val ) == NULL ) { 1049 return -1; 1050 } 1051 1052 ber_str2bv( at->sat_oid, 0, 0, &nval ); 1053 1054 if( attr_merge_one( e, ad_attributeTypes, &val, &nval ) ) 1055 { 1056 return -1; 1057 } 1058 ldap_memfree( val.bv_val ); 1059 } 1060 return 0; 1061 } 1062 1063 int 1064 register_at( const char *def, AttributeDescription **rad, int dupok ) 1065 { 1066 LDAPAttributeType *at; 1067 int code, freeit = 0; 1068 const char *err; 1069 AttributeDescription *ad = NULL; 1070 1071 at = ldap_str2attributetype( def, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); 1072 if ( !at ) { 1073 Debug( LDAP_DEBUG_ANY, 1074 "register_at: AttributeType \"%s\": %s, %s\n", 1075 def, ldap_scherr2str(code), err ); 1076 return code; 1077 } 1078 1079 code = at_add( at, 0, NULL, NULL, &err ); 1080 if ( code ) { 1081 if ( code == SLAP_SCHERR_ATTR_DUP && dupok ) { 1082 freeit = 1; 1083 1084 } else { 1085 Debug( LDAP_DEBUG_ANY, 1086 "register_at: AttributeType \"%s\": %s, %s\n", 1087 def, scherr2str(code), err ); 1088 ldap_attributetype_free( at ); 1089 return code; 1090 } 1091 } 1092 code = slap_str2ad( at->at_names[0], &ad, &err ); 1093 if ( freeit || code ) { 1094 ldap_attributetype_free( at ); 1095 } else { 1096 ldap_memfree( at ); 1097 } 1098 if ( code ) { 1099 Debug( LDAP_DEBUG_ANY, "register_at: AttributeType \"%s\": %s\n", 1100 def, err, 0 ); 1101 } 1102 if ( rad ) *rad = ad; 1103 return code; 1104 } 1105